• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.privacy
16 
17 import android.content.Context
18 import android.util.AttributeSet
19 import android.view.Gravity.CENTER_VERTICAL
20 import android.view.Gravity.END
21 import android.view.ViewGroup
22 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
23 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
24 import android.widget.ImageView
25 import android.widget.LinearLayout
26 import com.android.settingslib.Utils
27 import com.android.systemui.R
28 import com.android.systemui.animation.LaunchableFrameLayout
29 import com.android.systemui.statusbar.events.BackgroundAnimatableView
30 
31 class OngoingPrivacyChip @JvmOverloads constructor(
32     context: Context,
33     attrs: AttributeSet? = null,
34     defStyleAttrs: Int = 0,
35     defStyleRes: Int = 0
36 ) : LaunchableFrameLayout(context, attrs, defStyleAttrs, defStyleRes), BackgroundAnimatableView {
37 
38     private var iconMargin = 0
39     private var iconSize = 0
40     private var iconColor = 0
41 
42     private val iconsContainer: LinearLayout
43 
44     var privacyList = emptyList<PrivacyItem>()
45         set(value) {
46             field = value
47             updateView(PrivacyChipBuilder(context, field))
48         }
49 
50     init {
51         inflate(context, R.layout.ongoing_privacy_chip, this)
52         id = R.id.privacy_chip
53         layoutParams = LayoutParams(WRAP_CONTENT, MATCH_PARENT, CENTER_VERTICAL or END)
54         clipChildren = true
55         clipToPadding = true
56         iconsContainer = requireViewById(R.id.icons_container)
57         updateResources()
58     }
59 
60     /**
61      * When animating as a chip in the status bar, we want to animate the width for the container
62      * of the privacy items. We have to subtract our own top and left offset because the bounds
63      * come to us as absolute on-screen bounds, and `iconsContainer` is laid out relative to the
64      * frame layout's bounds.
65      */
66     override fun setBoundsForAnimation(l: Int, t: Int, r: Int, b: Int) {
67         iconsContainer.setLeftTopRightBottom(l - left, t - top, r - left, b - top)
68     }
69 
70     // Should only be called if the builder icons or app changed
71     private fun updateView(builder: PrivacyChipBuilder) {
72         fun setIcons(chipBuilder: PrivacyChipBuilder, iconsContainer: ViewGroup) {
73             iconsContainer.removeAllViews()
74             chipBuilder.generateIcons().forEachIndexed { i, it ->
75                 it.mutate()
76                 it.setTint(iconColor)
77                 val image = ImageView(context).apply {
78                     setImageDrawable(it)
79                     scaleType = ImageView.ScaleType.CENTER_INSIDE
80                 }
81                 iconsContainer.addView(image, iconSize, iconSize)
82                 if (i != 0) {
83                     val lp = image.layoutParams as MarginLayoutParams
84                     lp.marginStart = iconMargin
85                     image.layoutParams = lp
86                 }
87             }
88         }
89 
90         if (!privacyList.isEmpty()) {
91             generateContentDescription(builder)
92             setIcons(builder, iconsContainer)
93         } else {
94             iconsContainer.removeAllViews()
95         }
96         requestLayout()
97     }
98 
99     private fun generateContentDescription(builder: PrivacyChipBuilder) {
100         val typesText = builder.joinTypes()
101         contentDescription = context.getString(
102                 R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
103     }
104 
105     private fun updateResources() {
106         iconMargin = context.resources
107                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_margin)
108         iconSize = context.resources
109                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size)
110         iconColor =
111                 Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
112 
113         val padding = context.resources
114                 .getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
115         iconsContainer.setPaddingRelative(padding, 0, padding, 0)
116         iconsContainer.background = context.getDrawable(R.drawable.statusbar_privacy_chip_bg)
117     }
118 }