• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2021 The Android Open Source Project
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 
17 package com.android.systemui.statusbar.events
18 
19 import android.annotation.IntRange
20 import android.annotation.SuppressLint
21 import android.content.Context
22 import android.view.View
23 import android.widget.ImageView
24 import com.android.systemui.privacy.OngoingPrivacyChip
25 import com.android.systemui.privacy.PrivacyItem
26 import com.android.systemui.statusbar.BatteryStatusChip
27 import com.android.systemui.statusbar.ConnectedDisplayChip
28 
29 typealias ViewCreator = (context: Context) -> BackgroundAnimatableView
30 
31 interface StatusEvent {
32     val priority: Int
33     // Whether or not to force the status bar open and show a dot
34     var forceVisible: Boolean
35     // Whether or not to show an animation for this event
36     val showAnimation: Boolean
37     val viewCreator: ViewCreator
38     var contentDescription: String?
39     /**
40      * When true, an accessibility event with [contentDescription] is announced when the view
41      * becomes visible.
42      */
43     val shouldAnnounceAccessibilityEvent: Boolean
44 
45     // Update this event with values from another event.
46     fun updateFromEvent(other: StatusEvent?) {
47         // no op by default
48     }
49 
50     // Whether or not this event should update its value from the provided. False by default
51     fun shouldUpdateFromEvent(other: StatusEvent?): Boolean {
52         return false
53     }
54 }
55 
56 class BGView(
57     context: Context
58 ) : View(context), BackgroundAnimatableView {
59     override val view: View
60         get() = this
61 
setBoundsForAnimationnull62     override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
63         setLeftTopRightBottom(l, t, r, b)
64     }
65 }
66 
67 @SuppressLint("AppCompatCustomView")
68 class BGImageView(
69     context: Context
70 ) : ImageView(context), BackgroundAnimatableView {
71     override val view: View
72         get() = this
73 
setBoundsForAnimationnull74     override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
75         setLeftTopRightBottom(l, t, r, b)
76     }
77 }
78 
79 class BatteryEvent(@IntRange(from = 0, to = 100) val batteryLevel: Int) : StatusEvent {
80     override val priority = 50
81     override var forceVisible = false
82     override val showAnimation = true
83     override var contentDescription: String? = ""
84     override val shouldAnnounceAccessibilityEvent: Boolean = false
85 
contextnull86     override val viewCreator: ViewCreator = { context ->
87         BatteryStatusChip(context).apply {
88             setBatteryLevel(batteryLevel)
89         }
90     }
91 
toStringnull92     override fun toString(): String {
93         return javaClass.simpleName
94     }
95 }
96 
97 /** Event that triggers a connected display chip in the status bar. */
98 class ConnectedDisplayEvent : StatusEvent {
99     /** Priority is set higher than [BatteryEvent]. */
100     override val priority = 60
101     override var forceVisible = false
102     override val showAnimation = true
103     override var contentDescription: String? = ""
104     override val shouldAnnounceAccessibilityEvent: Boolean = true
105 
contextnull106     override val viewCreator: ViewCreator = { context ->
107         ConnectedDisplayChip(context)
108     }
109 
toStringnull110     override fun toString(): String {
111         return javaClass.simpleName
112     }
113 }
114 
115 /** open only for testing purposes. (See [FakeStatusEvent.kt]) */
116 open class PrivacyEvent(override val showAnimation: Boolean = true) : StatusEvent {
117     override var contentDescription: String? = null
118     override val priority = 100
119     override var forceVisible = true
120     override val shouldAnnounceAccessibilityEvent: Boolean = false
121     var privacyItems: List<PrivacyItem> = listOf()
122     private var privacyChip: OngoingPrivacyChip? = null
123 
contextnull124     override val viewCreator: ViewCreator = { context ->
125         val v = OngoingPrivacyChip(context)
126         v.privacyList = privacyItems
127         v.contentDescription = contentDescription
128         privacyChip = v
129         v
130     }
131 
toStringnull132     override fun toString(): String {
133         return "${javaClass.simpleName}(forceVisible=$forceVisible, privacyItems=$privacyItems)"
134     }
135 
shouldUpdateFromEventnull136     override fun shouldUpdateFromEvent(other: StatusEvent?): Boolean {
137         return other is PrivacyEvent && (other.privacyItems != privacyItems ||
138                 other.contentDescription != contentDescription ||
139                 (other.forceVisible && !forceVisible))
140     }
141 
updateFromEventnull142     override fun updateFromEvent(other: StatusEvent?) {
143         if (other !is PrivacyEvent) {
144             return
145         }
146 
147         privacyItems = other.privacyItems
148         contentDescription = other.contentDescription
149 
150         privacyChip?.contentDescription = other.contentDescription
151         privacyChip?.privacyList = other.privacyItems
152 
153         if (other.forceVisible) forceVisible = true
154     }
155 }
156