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 }