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.mobile.ui.view 18 19 import android.content.Context 20 import android.util.AttributeSet 21 import android.view.LayoutInflater 22 import android.widget.FrameLayout 23 import android.widget.ImageView 24 import com.android.settingslib.flags.Flags.newStatusBarIcons 25 import com.android.systemui.kairos.BuildSpec 26 import com.android.systemui.kairos.ExperimentalKairosApi 27 import com.android.systemui.kairos.KairosNetwork 28 import com.android.systemui.res.R 29 import com.android.systemui.statusbar.StatusBarIconView.getVisibleStateString 30 import com.android.systemui.statusbar.core.NewStatusBarIcons 31 import com.android.systemui.statusbar.phone.StatusBarLocation 32 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger 33 import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder 34 import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinderKairos 35 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel 36 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModelKairos 37 import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView 38 import kotlinx.coroutines.CoroutineScope 39 import kotlinx.coroutines.Job 40 41 class ModernStatusBarMobileView(context: Context, attrs: AttributeSet?) : 42 ModernStatusBarView(context, attrs) { 43 44 var subId: Int = -1 45 toStringnull46 override fun toString(): String { 47 return "ModernStatusBarMobileView(" + 48 "slot='$slot', " + 49 "subId=$subId, " + 50 "isCollecting=${binding.isCollecting()}, " + 51 "visibleState=${getVisibleStateString(visibleState)}); " + 52 "viewString=${super.toString()}" 53 } 54 55 companion object { 56 57 /** 58 * Inflates a new instance of [ModernStatusBarMobileView], binds it to [viewModel], and 59 * returns it. 60 */ 61 @JvmStatic constructAndBindnull62 fun constructAndBind( 63 context: Context, 64 logger: MobileViewLogger, 65 slot: String, 66 viewModel: LocationBasedMobileViewModel, 67 ): ModernStatusBarMobileView { 68 return (LayoutInflater.from(context) 69 .inflate(R.layout.status_bar_mobile_signal_group_new, null) 70 as ModernStatusBarMobileView) 71 .also { 72 // Flag-specific configuration 73 if (NewStatusBarIcons.isEnabled) { 74 // triangle 75 it.requireViewById<ImageView>(R.id.mobile_signal).apply { 76 layoutParams.height = 77 context.resources.getDimensionPixelSize( 78 R.dimen.status_bar_mobile_signal_size_updated 79 ) 80 } 81 82 // RAT indicator container 83 it.requireViewById<FrameLayout>(R.id.mobile_type_container).apply { 84 (layoutParams as MarginLayoutParams).marginEnd = 85 context.resources.getDimensionPixelSize( 86 R.dimen.status_bar_mobile_container_margin_end 87 ) 88 layoutParams.height = 89 context.resources.getDimensionPixelSize( 90 R.dimen.status_bar_mobile_container_height_updated 91 ) 92 } 93 94 // RAT indicator 95 it.requireViewById<ImageView>(R.id.mobile_type).apply { 96 layoutParams.height = 97 context.resources.getDimensionPixelSize( 98 R.dimen.status_bar_mobile_type_size_updated 99 ) 100 } 101 } 102 103 it.subId = viewModel.subscriptionId 104 it.initView(slot) { 105 MobileIconBinder.bind(view = it, viewModel = viewModel, logger = logger) 106 } 107 logger.logNewViewBinding(it, viewModel) 108 } 109 } 110 111 /** 112 * Inflates a new instance of [ModernStatusBarMobileView], binds it to [viewModel], and 113 * returns it. 114 */ 115 @ExperimentalKairosApi 116 @JvmStatic constructAndBindnull117 fun constructAndBind( 118 context: Context, 119 logger: MobileViewLogger, 120 slot: String, 121 viewModel: BuildSpec<LocationBasedMobileViewModelKairos>, 122 scope: CoroutineScope, 123 subscriptionId: Int, 124 location: StatusBarLocation, 125 kairosNetwork: KairosNetwork, 126 ): Pair<ModernStatusBarMobileView, Job> { 127 val view = 128 (LayoutInflater.from(context) 129 .inflate(R.layout.status_bar_mobile_signal_group_new, null) 130 as ModernStatusBarMobileView) 131 .apply { 132 // Flag-specific configuration 133 if (newStatusBarIcons()) { 134 // New icon (with no embedded whitespace) is slightly shorter 135 // (but actually taller) 136 val iconView = requireViewById<ImageView>(R.id.mobile_signal) 137 val lp = iconView.layoutParams 138 lp.height = 139 context.resources.getDimensionPixelSize( 140 R.dimen.status_bar_mobile_signal_size_updated 141 ) 142 } 143 144 subId = subscriptionId 145 } 146 147 lateinit var jobResult: Job 148 view.initView(slot) { 149 val (binding, job) = 150 MobileIconBinderKairos.bind( 151 view = view, 152 viewModel = viewModel, 153 logger = logger, 154 scope = scope, 155 kairosNetwork = kairosNetwork, 156 ) 157 jobResult = job 158 binding 159 } 160 logger.logNewViewBinding(view, viewModel, location.name) 161 return view to jobResult 162 } 163 } 164 } 165