1 /*
<lambda>null2  * Copyright (C) 2019 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.notification.row
18 
19 import android.app.NotificationChannel
20 import android.app.NotificationManager.IMPORTANCE_DEFAULT
21 import android.app.NotificationManager.IMPORTANCE_NONE
22 import android.app.NotificationManager.IMPORTANCE_UNSPECIFIED
23 import android.content.Context
24 import android.graphics.drawable.Drawable
25 import android.text.TextUtils
26 import android.transition.AutoTransition
27 import android.transition.Transition
28 import android.transition.TransitionManager
29 import android.util.AttributeSet
30 import android.view.LayoutInflater
31 import android.view.View
32 import android.widget.ImageView
33 import android.widget.LinearLayout
34 import android.widget.Switch
35 import android.widget.TextView
36 
37 import com.android.systemui.R
38 
39 /**
40  * Half-shelf for notification channel controls
41  */
42 class ChannelEditorListView(c: Context, attrs: AttributeSet) : LinearLayout(c, attrs) {
43     lateinit var controller: ChannelEditorDialogController
44     var appIcon: Drawable? = null
45     var appName: String? = null
46     var channels = mutableListOf<NotificationChannel>()
47         set(newValue) {
48             field = newValue
49             updateRows()
50         }
51 
52     // The first row is for the entire app
53     private lateinit var appControlRow: AppControlView
54 
55     override fun onFinishInflate() {
56         super.onFinishInflate()
57 
58         appControlRow = findViewById(R.id.app_control)
59     }
60 
61     private fun updateRows() {
62         val enabled = controller.appNotificationsEnabled
63 
64         val transition = AutoTransition()
65         transition.duration = 200
66         transition.addListener(object : Transition.TransitionListener {
67             override fun onTransitionEnd(p0: Transition?) {
68                 notifySubtreeAccessibilityStateChangedIfNeeded()
69             }
70 
71             override fun onTransitionResume(p0: Transition?) {
72             }
73 
74             override fun onTransitionPause(p0: Transition?) {
75             }
76 
77             override fun onTransitionCancel(p0: Transition?) {
78             }
79 
80             override fun onTransitionStart(p0: Transition?) {
81             }
82         })
83         TransitionManager.beginDelayedTransition(this, transition)
84 
85         // Remove any rows
86         val n = childCount
87         for (i in n.downTo(0)) {
88             val child = getChildAt(i)
89             if (child is ChannelRow) {
90                 removeView(child)
91             }
92         }
93 
94         updateAppControlRow(enabled)
95 
96         if (enabled) {
97             val inflater = LayoutInflater.from(context)
98             for (channel in channels) {
99                 addChannelRow(channel, inflater)
100             }
101         }
102     }
103 
104     private fun addChannelRow(channel: NotificationChannel, inflater: LayoutInflater) {
105         val row = inflater.inflate(R.layout.notif_half_shelf_row, null) as ChannelRow
106         row.controller = controller
107         row.channel = channel
108         addView(row)
109     }
110 
111     private fun updateAppControlRow(enabled: Boolean) {
112         appControlRow.iconView.setImageDrawable(appIcon)
113         appControlRow.channelName.text = context.resources
114                 .getString(R.string.notification_channel_dialog_title, appName)
115         appControlRow.switch.isChecked = enabled
116         appControlRow.switch.setOnCheckedChangeListener { _, b ->
117             controller.appNotificationsEnabled = b
118             updateRows()
119         }
120     }
121 }
122 
123 class AppControlView(c: Context, attrs: AttributeSet) : LinearLayout(c, attrs) {
124     lateinit var iconView: ImageView
125     lateinit var channelName: TextView
126     lateinit var switch: Switch
127 
onFinishInflatenull128     override fun onFinishInflate() {
129         iconView = findViewById(R.id.icon)
130         channelName = findViewById(R.id.app_name)
131         switch = findViewById(R.id.toggle)
132     }
133 }
134 
135 class ChannelRow(c: Context, attrs: AttributeSet) : LinearLayout(c, attrs) {
136 
137     lateinit var controller: ChannelEditorDialogController
138     private lateinit var channelName: TextView
139     private lateinit var channelDescription: TextView
140     private lateinit var switch: Switch
141     var gentle = false
142 
143     var channel: NotificationChannel? = null
144         set(newValue) {
145             field = newValue
146             updateImportance()
147             updateViews()
148         }
149 
onFinishInflatenull150     override fun onFinishInflate() {
151         channelName = findViewById(R.id.channel_name)
152         channelDescription = findViewById(R.id.channel_description)
153         switch = findViewById(R.id.toggle)
154         switch.setOnCheckedChangeListener { _, b ->
155             channel?.let {
156                 controller.proposeEditForChannel(it, if (b) it.importance else IMPORTANCE_NONE)
157             }
158         }
159     }
160 
updateViewsnull161     private fun updateViews() {
162         val nc = channel ?: return
163 
164         channelName.text = nc.name ?: ""
165 
166         nc.group?.let { groupId ->
167             channelDescription.text = controller.groupNameForId(groupId)
168         }
169 
170         if (nc.group == null || TextUtils.isEmpty(channelDescription.text)) {
171             channelDescription.visibility = View.GONE
172         } else {
173             channelDescription.visibility = View.VISIBLE
174         }
175 
176         switch.isChecked = nc.importance != IMPORTANCE_NONE
177     }
178 
updateImportancenull179     private fun updateImportance() {
180         val importance = channel?.importance ?: 0
181         gentle = importance != IMPORTANCE_UNSPECIFIED && importance < IMPORTANCE_DEFAULT
182     }
183 }
184