Update Split Shade's status bar font size
When the system's Font Size is changed, the config listener in LargeScreenShadeHeaderController changes the font size of Clock, DateView, and the Carrier Group. Bug: 222695062 Test: manually, with different font size and display size + atest com.android.systemui.statusbar.phone.LargeScreenShadeHeaderControllerTest Change-Id: I535a3e3afd7b8539422eb44b90de87a251002195
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui;
|
||||
|
||||
import android.annotation.StyleRes;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
@@ -23,9 +25,9 @@ import android.widget.TextView;
|
||||
/**
|
||||
* Utility class to update the font size when the configuration has changed.
|
||||
*/
|
||||
public class FontSizeUtils {
|
||||
public final class FontSizeUtils {
|
||||
|
||||
public static final float LARGE_TEXT_SCALE = 1.3f;
|
||||
private FontSizeUtils() {}
|
||||
|
||||
public static void updateFontSize(View parent, int viewId, int dimensId) {
|
||||
updateFontSize((TextView) parent.findViewById(viewId), dimensId);
|
||||
@@ -37,4 +39,20 @@ public class FontSizeUtils {
|
||||
v.getResources().getDimensionPixelSize(dimensId));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the font size according to the style given.
|
||||
*
|
||||
* @param v Text to update.
|
||||
* @param resId Style applying to the text.
|
||||
*/
|
||||
public static void updateFontSizeFromStyle(TextView v, @StyleRes int resId) {
|
||||
int[] attrs = {android.R.attr.textSize};
|
||||
int indexOfAttrTextSize = 0;
|
||||
TypedArray ta = v.getContext().obtainStyledAttributes(resId, attrs);
|
||||
int updatedTextPixelSize = ta.getDimensionPixelSize(indexOfAttrTextSize,
|
||||
(int) v.getTextSize());
|
||||
v.setTextSize(TypedValue.COMPLEX_UNIT_PX, updatedTextPixelSize);
|
||||
ta.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.qs.carrier;
|
||||
|
||||
import android.annotation.StyleRes;
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.text.TextUtils;
|
||||
@@ -30,6 +31,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.graph.SignalDrawable;
|
||||
import com.android.systemui.FontSizeUtils;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.Objects;
|
||||
@@ -146,4 +148,8 @@ public class QSCarrier extends LinearLayout {
|
||||
public void setCarrierText(CharSequence text) {
|
||||
mCarrierText.setText(text);
|
||||
}
|
||||
|
||||
public void updateTextAppearance(@StyleRes int resId) {
|
||||
FontSizeUtils.updateFontSizeFromStyle(mCarrierText, resId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
package com.android.systemui.qs.carrier;
|
||||
|
||||
import android.annotation.StyleRes;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.FontSizeUtils;
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
@@ -55,4 +57,11 @@ public class QSCarrierGroup extends LinearLayout {
|
||||
View getCarrierDivider2() {
|
||||
return findViewById(R.id.qs_carrier_divider2);
|
||||
}
|
||||
|
||||
public void updateTextAppearance(@StyleRes int resId) {
|
||||
FontSizeUtils.updateFontSizeFromStyle(getNoSimTextView(), resId);
|
||||
getCarrier1View().updateTextAppearance(resId);
|
||||
getCarrier2View().updateTextAppearance(resId);
|
||||
getCarrier3View().updateTextAppearance(resId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.android.systemui.statusbar.phone
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.systemui.Dumpable
|
||||
import com.android.systemui.FontSizeUtils
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.animation.ShadeInterpolation
|
||||
import com.android.systemui.battery.BatteryMeterView
|
||||
@@ -30,10 +32,12 @@ import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.qs.ChipVisibilityListener
|
||||
import com.android.systemui.qs.HeaderPrivacyIconsController
|
||||
import com.android.systemui.qs.carrier.QSCarrierGroup
|
||||
import com.android.systemui.qs.carrier.QSCarrierGroupController
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
|
||||
import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER
|
||||
import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import java.io.PrintWriter
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Named
|
||||
@@ -43,6 +47,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
||||
@Named(LARGE_SCREEN_SHADE_HEADER) private val header: View,
|
||||
private val statusBarIconController: StatusBarIconController,
|
||||
private val privacyIconsController: HeaderPrivacyIconsController,
|
||||
private val configurationController: ConfigurationController,
|
||||
qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
|
||||
featureFlags: FeatureFlags,
|
||||
@Named(LARGE_SCREEN_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController,
|
||||
@@ -69,6 +74,9 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
||||
private val iconContainer: StatusIconContainer
|
||||
private val carrierIconSlots: List<String>
|
||||
private val qsCarrierGroupController: QSCarrierGroupController
|
||||
private val clock: TextView = header.findViewById(R.id.clock)
|
||||
private val date: TextView = header.findViewById(R.id.date)
|
||||
private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group)
|
||||
|
||||
private var qsDisabled = false
|
||||
|
||||
@@ -148,9 +156,9 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
||||
.load(context, resources.getXml(R.xml.large_screen_shade_header))
|
||||
privacyIconsController.chipVisibilityListener = chipVisibilityListener
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
bindConfigurationListener()
|
||||
|
||||
batteryMeterViewController.init()
|
||||
val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon)
|
||||
|
||||
@@ -194,6 +202,18 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindConfigurationListener() {
|
||||
val listener = object : ConfigurationController.ConfigurationListener {
|
||||
override fun onDensityOrFontScaleChanged() {
|
||||
val qsStatusStyle = R.style.TextAppearance_QS_Status
|
||||
FontSizeUtils.updateFontSizeFromStyle(clock, qsStatusStyle)
|
||||
FontSizeUtils.updateFontSizeFromStyle(date, qsStatusStyle)
|
||||
qsCarrierGroup.updateTextAppearance(qsStatusStyle)
|
||||
}
|
||||
}
|
||||
configurationController.addCallback(listener)
|
||||
}
|
||||
|
||||
private fun onShadeExpandedChanged() {
|
||||
if (shadeExpanded) {
|
||||
privacyIconsController.startListening()
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package com.android.systemui.statusbar.phone
|
||||
|
||||
import android.app.StatusBarManager
|
||||
import android.content.Context
|
||||
import android.content.res.TypedArray
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.util.TypedValue.COMPLEX_UNIT_PX
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
@@ -13,7 +17,9 @@ import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.qs.HeaderPrivacyIconsController
|
||||
import com.android.systemui.qs.carrier.QSCarrierGroup
|
||||
import com.android.systemui.qs.carrier.QSCarrierGroupController
|
||||
import com.android.systemui.statusbar.policy.FakeConfigurationController
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@@ -22,6 +28,7 @@ import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.clearInvocations
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
@@ -36,19 +43,32 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
||||
@Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController
|
||||
@Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder
|
||||
@Mock private lateinit var featureFlags: FeatureFlags
|
||||
@Mock private lateinit var clock: TextView
|
||||
@Mock private lateinit var date: TextView
|
||||
@Mock private lateinit var carrierGroup: QSCarrierGroup
|
||||
@Mock private lateinit var batteryMeterView: BatteryMeterView
|
||||
@Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
|
||||
@Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
|
||||
@Mock private lateinit var dumpManager: DumpManager
|
||||
|
||||
@Mock private lateinit var mockedContext: Context
|
||||
@Mock private lateinit var typedArray: TypedArray
|
||||
|
||||
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
|
||||
var viewVisibility = View.GONE
|
||||
|
||||
private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController
|
||||
private lateinit var carrierIconSlots: List<String>
|
||||
private val configurationController = FakeConfigurationController()
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
whenever<TextView>(view.findViewById(R.id.clock)).thenReturn(clock)
|
||||
whenever(clock.context).thenReturn(mockedContext)
|
||||
whenever(mockedContext.obtainStyledAttributes(anyInt(), any())).thenReturn(typedArray)
|
||||
whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date)
|
||||
whenever(date.context).thenReturn(mockedContext)
|
||||
whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup)
|
||||
whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon))
|
||||
.thenReturn(batteryMeterView)
|
||||
whenever<StatusIconContainer>(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons)
|
||||
@@ -67,6 +87,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
||||
view,
|
||||
statusBarIconController,
|
||||
privacyIconsController,
|
||||
configurationController,
|
||||
qsCarrierGroupControllerBuilder,
|
||||
featureFlags,
|
||||
batteryMeterViewController,
|
||||
@@ -138,4 +159,38 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
|
||||
mLargeScreenShadeHeaderController.active = true
|
||||
mLargeScreenShadeHeaderController.shadeExpanded = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateConfig_changesFontSize() {
|
||||
val updatedTextPixelSize = 32
|
||||
setReturnTextSize(updatedTextPixelSize)
|
||||
|
||||
configurationController.notifyDensityOrFontScaleChanged()
|
||||
|
||||
verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize.toFloat())
|
||||
verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize.toFloat())
|
||||
verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateConfig_changesFontSizeMultipleTimes() {
|
||||
val updatedTextPixelSize1 = 32
|
||||
setReturnTextSize(updatedTextPixelSize1)
|
||||
configurationController.notifyDensityOrFontScaleChanged()
|
||||
verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize1.toFloat())
|
||||
verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize1.toFloat())
|
||||
verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
|
||||
clearInvocations(carrierGroup)
|
||||
|
||||
val updatedTextPixelSize2 = 42
|
||||
setReturnTextSize(updatedTextPixelSize2)
|
||||
configurationController.notifyDensityOrFontScaleChanged()
|
||||
verify(clock).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize2.toFloat())
|
||||
verify(date).setTextSize(COMPLEX_UNIT_PX, updatedTextPixelSize2.toFloat())
|
||||
verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status)
|
||||
}
|
||||
|
||||
private fun setReturnTextSize(resultTextSize: Int) {
|
||||
whenever(typedArray.getDimensionPixelSize(anyInt(), anyInt())).thenReturn(resultTextSize)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ class FakeConfigurationController : ConfigurationController {
|
||||
listeners.forEach { it.onThemeChanged() }
|
||||
}
|
||||
|
||||
fun notifyDensityOrFontScaleChanged() {
|
||||
listeners.forEach { it.onDensityOrFontScaleChanged() }
|
||||
}
|
||||
|
||||
fun notifyConfigurationChanged() {
|
||||
onConfigurationChanged(newConfiguration = null)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user