1 /* 2 * Copyright (C) 2022 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.pipeline.shared.ui.view 18 19 import android.content.Context 20 import android.graphics.Rect 21 import android.util.AttributeSet 22 import android.view.Gravity 23 import com.android.systemui.R 24 import com.android.systemui.plugins.DarkIconDispatcher 25 import com.android.systemui.statusbar.BaseStatusBarFrameLayout 26 import com.android.systemui.statusbar.StatusBarIconView 27 import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT 28 import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN 29 import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding 30 31 /** 32 * A new and more modern implementation of [BaseStatusBarFrameLayout] that gets updated by view 33 * binders communicating via [ModernStatusBarViewBinding]. 34 */ 35 open class ModernStatusBarView(context: Context, attrs: AttributeSet?) : 36 BaseStatusBarFrameLayout(context, attrs) { 37 38 private lateinit var slot: String 39 internal lateinit var binding: ModernStatusBarViewBinding 40 41 @StatusBarIconView.VisibleState 42 private var iconVisibleState: Int = STATE_HIDDEN 43 set(value) { 44 if (field == value) { 45 return 46 } 47 field = value 48 binding.onVisibilityStateChanged(value) 49 } 50 getSlotnull51 override fun getSlot() = slot 52 53 override fun onDarkChanged(areas: ArrayList<Rect>?, darkIntensity: Float, tint: Int) { 54 val newTint = DarkIconDispatcher.getTint(areas, this, tint) 55 binding.onIconTintChanged(newTint) 56 binding.onDecorTintChanged(newTint) 57 } 58 setStaticDrawableColornull59 override fun setStaticDrawableColor(color: Int) { 60 binding.onIconTintChanged(color) 61 } 62 setDecorColornull63 override fun setDecorColor(color: Int) { 64 binding.onDecorTintChanged(color) 65 } 66 setVisibleStatenull67 override fun setVisibleState(@StatusBarIconView.VisibleState state: Int, animate: Boolean) { 68 iconVisibleState = state 69 } 70 71 @StatusBarIconView.VisibleState getVisibleStatenull72 override fun getVisibleState(): Int { 73 return iconVisibleState 74 } 75 isIconVisiblenull76 override fun isIconVisible(): Boolean { 77 return binding.getShouldIconBeVisible() 78 } 79 80 /** See [StatusBarIconView.getDrawingRect]. */ getDrawingRectnull81 override fun getDrawingRect(outRect: Rect) { 82 super.getDrawingRect(outRect) 83 val translationX = translationX.toInt() 84 val translationY = translationY.toInt() 85 outRect.left += translationX 86 outRect.right += translationX 87 outRect.top += translationY 88 outRect.bottom += translationY 89 } 90 91 /** 92 * Initializes this view. 93 * 94 * Creates a dot view, and uses [bindingCreator] to get and set the binding. 95 */ initViewnull96 fun initView(slot: String, bindingCreator: () -> ModernStatusBarViewBinding) { 97 // The dot view requires [slot] to be set, and the [binding] may require an instantiated dot 98 // view. So, this is the required order. 99 this.slot = slot 100 initDotView() 101 this.binding = bindingCreator.invoke() 102 } 103 104 /** 105 * Creates a [StatusBarIconView] that is always in DOT mode and adds it to this view. 106 * 107 * Mostly duplicated from [com.android.systemui.statusbar.StatusBarWifiView] and 108 * [com.android.systemui.statusbar.StatusBarMobileView]. 109 */ initDotViewnull110 private fun initDotView() { 111 // TODO(b/238425913): Could we just have this dot view be part of the layout with a dot 112 // drawable so we don't need to inflate it manually? Would that not work with animations? 113 val dotView = 114 StatusBarIconView(mContext, slot, null).also { 115 it.id = R.id.status_bar_dot 116 // Hard-code this view to always be in the DOT state so that whenever it's visible 117 // it will show a dot 118 it.visibleState = STATE_DOT 119 } 120 121 val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size) 122 val lp = LayoutParams(width, width) 123 lp.gravity = Gravity.CENTER_VERTICAL or Gravity.START 124 addView(dotView, lp) 125 } 126 } 127