1 /* 2 * Copyright (C) 2017 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 package com.android.systemui.statusbar.phone 17 18 import android.annotation.IntDef 19 import android.content.Context 20 import android.graphics.drawable.Icon 21 import android.os.UserHandle 22 import com.android.internal.statusbar.StatusBarIcon 23 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState 24 import com.android.systemui.statusbar.pipeline.icons.shared.model.ModernStatusBarViewCreator 25 26 /** Wraps [com.android.internal.statusbar.StatusBarIcon] so we can still have a uniform list */ 27 open class StatusBarIconHolder private constructor() { 28 @IntDef(TYPE_ICON, TYPE_MOBILE_NEW, TYPE_WIFI_NEW, TYPE_BINDABLE) 29 @Retention(AnnotationRetention.SOURCE) 30 internal annotation class IconType 31 32 var icon: StatusBarIcon? = null 33 34 @IconType 35 open var type = TYPE_ICON 36 internal set 37 38 var tag = 0 39 private set 40 41 open var isVisible: Boolean 42 get() = 43 when (type) { 44 TYPE_ICON -> icon!!.visible 45 46 // The new pipeline controls visibilities via the view model and 47 // view binder, so 48 // this is effectively an unused return value. 49 TYPE_BINDABLE, 50 TYPE_MOBILE_NEW, 51 TYPE_WIFI_NEW -> true 52 else -> true 53 } 54 set(visible) { 55 if (isVisible == visible) { 56 return 57 } 58 when (type) { 59 TYPE_ICON -> icon!!.visible = visible 60 TYPE_BINDABLE, 61 TYPE_MOBILE_NEW, 62 TYPE_WIFI_NEW -> {} 63 } 64 } 65 toStringnull66 override fun toString(): String { 67 return ("StatusBarIconHolder(type=${getTypeString(type)}" + 68 " tag=$tag" + 69 " visible=$isVisible)") 70 } 71 72 companion object { 73 const val TYPE_ICON = 0 74 75 /** 76 * TODO (b/249790733): address this once the new pipeline is in place This type exists so 77 * that the new pipeline (see [MobileIconViewModel]) can be used to inform the old view 78 * system about changes to the data set (the list of mobile icons). The design of the new 79 * pipeline should allow for removal of this icon holder type, and obsolete the need for 80 * this entire class. 81 */ 82 @Deprecated( 83 """This field only exists so the new status bar pipeline can interface with the 84 view holder system.""" 85 ) 86 const val TYPE_MOBILE_NEW = 3 87 88 /** 89 * TODO (b/238425913): address this once the new pipeline is in place This type exists so 90 * that the new wifi pipeline can be used to inform the old view system about the existence 91 * of the wifi icon. The design of the new pipeline should allow for removal of this icon 92 * holder type, and obsolete the need for this entire class. 93 */ 94 @Deprecated( 95 """This field only exists so the new status bar pipeline can interface with the 96 view holder system.""" 97 ) 98 const val TYPE_WIFI_NEW = 4 99 100 /** Only applicable to [BindableIconHolder] */ 101 const val TYPE_BINDABLE = 5 102 103 /** Returns a human-readable string representing the given type. */ getTypeStringnull104 fun getTypeString(@IconType type: Int): String { 105 return when (type) { 106 TYPE_ICON -> "ICON" 107 TYPE_MOBILE_NEW -> "MOBILE_NEW" 108 TYPE_WIFI_NEW -> "WIFI_NEW" 109 else -> "UNKNOWN" 110 } 111 } 112 113 @JvmStatic fromIconnull114 fun fromIcon(icon: StatusBarIcon?): StatusBarIconHolder { 115 val wrapper = StatusBarIconHolder() 116 wrapper.icon = icon 117 return wrapper 118 } 119 120 /** Creates a new holder with for the new wifi icon. */ 121 @JvmStatic forNewWifiIconnull122 fun forNewWifiIcon(): StatusBarIconHolder { 123 val holder = StatusBarIconHolder() 124 holder.type = TYPE_WIFI_NEW 125 return holder 126 } 127 128 /** 129 * ONLY for use with the new connectivity pipeline, where we only need a subscriptionID to 130 * determine icon ordering and building the correct view model 131 */ 132 @JvmStatic fromSubIdForModernMobileIconnull133 fun fromSubIdForModernMobileIcon(subId: Int): StatusBarIconHolder { 134 val holder = StatusBarIconHolder() 135 holder.type = TYPE_MOBILE_NEW 136 holder.tag = subId 137 return holder 138 } 139 140 /** Creates a new StatusBarIconHolder from a CallIndicatorIconState. */ 141 @JvmStatic fromCallIndicatorStatenull142 fun fromCallIndicatorState( 143 context: Context, 144 state: CallIndicatorIconState, 145 ): StatusBarIconHolder { 146 val holder = StatusBarIconHolder() 147 val resId = if (state.isNoCalling) state.noCallingResId else state.callStrengthResId 148 val contentDescription = 149 if (state.isNoCalling) state.noCallingDescription else state.callStrengthDescription 150 holder.icon = 151 StatusBarIcon( 152 UserHandle.SYSTEM, 153 context.packageName, 154 Icon.createWithResource(context, resId), 155 0, 156 0, 157 contentDescription, 158 StatusBarIcon.Type.SystemIcon, 159 ) 160 holder.tag = state.subId 161 return holder 162 } 163 } 164 165 /** 166 * Subclass of StatusBarIconHolder that is responsible only for the registration of an icon into 167 * the [StatusBarIconList]. A bindable icon takes care of its own display, including hiding 168 * itself under the correct conditions. 169 * 170 * StatusBarIconController will register all available bindable icons on init (see 171 * [BindableIconsRepository]), and will ignore any call to setIcon for these. 172 * 173 * @property initializer a view creator that can bind the relevant view models to the created 174 * view. 175 * @property slot the name of the slot that this holder is used for. 176 */ 177 class BindableIconHolder(val initializer: ModernStatusBarViewCreator, val slot: String) : 178 StatusBarIconHolder() { 179 override var type: Int = TYPE_BINDABLE 180 181 /** This is unused, as bindable icons use their own view binders to control visibility */ 182 override var isVisible: Boolean = true 183 toStringnull184 override fun toString(): String { 185 return ("StatusBarIconHolder(type=BINDABLE, slot=$slot)") 186 } 187 } 188 } 189