Merge changes If1a0855e,I5a079522 into udc-qpr-dev
* changes: fix(non linear font scaling): fix QQS clock text right padding may not proper when font sclaing changed fix(non linear font scaling): fix status bar icons and dot be cut off or wrong posistion
This commit is contained in:
@@ -275,6 +275,7 @@ constructor(
|
||||
lastInsets?.let { updateConstraintsForInsets(header, it) }
|
||||
updateResources()
|
||||
updateCarrierGroupPadding()
|
||||
clock.onDensityOrFontScaleChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,9 +448,14 @@ public class NotificationIconContainer extends ViewGroup {
|
||||
@VisibleForTesting
|
||||
boolean isOverflowing(boolean isLastChild, float translationX, float layoutEnd,
|
||||
float iconSize) {
|
||||
// Layout end, as used here, does not include padding end.
|
||||
final float overflowX = isLastChild ? layoutEnd : layoutEnd - iconSize;
|
||||
return translationX >= overflowX;
|
||||
if (isLastChild) {
|
||||
return translationX + iconSize > layoutEnd;
|
||||
} else {
|
||||
// If the child is not the last child, we need to ensure that we have room for the next
|
||||
// icon and the dot. The dot could be as large as an icon, so verify that we have room
|
||||
// for 2 icons.
|
||||
return translationX + iconSize * 2f > layoutEnd;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -490,10 +495,7 @@ public class NotificationIconContainer extends ViewGroup {
|
||||
// First icon to overflow.
|
||||
if (firstOverflowIndex == -1 && isOverflowing) {
|
||||
firstOverflowIndex = i;
|
||||
mVisualOverflowStart = layoutEnd - mIconSize;
|
||||
if (forceOverflow || mIsStaticLayout) {
|
||||
mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
|
||||
}
|
||||
mVisualOverflowStart = translationX;
|
||||
}
|
||||
final float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
|
||||
? ((StatusBarIconView) view).getIconScaleIncreased()
|
||||
|
||||
@@ -22,6 +22,8 @@ import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
@@ -73,13 +75,16 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
||||
// Any ignored icon will never be added as a child
|
||||
private ArrayList<String> mIgnoredSlots = new ArrayList<>();
|
||||
|
||||
private Configuration mConfiguration;
|
||||
|
||||
public StatusIconContainer(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public StatusIconContainer(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initDimens();
|
||||
mConfiguration = new Configuration(context.getResources().getConfiguration());
|
||||
reloadDimens();
|
||||
setWillNotDraw(!DEBUG_OVERFLOW);
|
||||
}
|
||||
|
||||
@@ -100,7 +105,7 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
||||
return mShouldRestrictIcons;
|
||||
}
|
||||
|
||||
private void initDimens() {
|
||||
private void reloadDimens() {
|
||||
// This is the same value that StatusBarIconView uses
|
||||
mIconDotFrameWidth = getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.status_bar_icon_size_sp);
|
||||
@@ -233,6 +238,16 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
||||
child.setTag(R.id.status_bar_view_state_tag, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
final int configDiff = newConfig.diff(mConfiguration);
|
||||
mConfiguration.setTo(newConfig);
|
||||
if ((configDiff & (ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
|
||||
reloadDimens();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a name of an icon slot to be ignored. It will not show up nor be measured
|
||||
* @param slotName name of the icon as it exists in
|
||||
@@ -342,13 +357,17 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
||||
int totalVisible = mLayoutStates.size();
|
||||
int maxVisible = totalVisible <= MAX_ICONS ? MAX_ICONS : MAX_ICONS - 1;
|
||||
|
||||
mUnderflowStart = 0;
|
||||
// Init mUnderflowStart value with the offset to let the dot be placed next to battery icon.
|
||||
// This is to prevent if the underflow happens at rightest(totalVisible - 1) child then
|
||||
// break the for loop with mUnderflowStart staying 0(initial value), causing the dot be
|
||||
// placed at the leftest side.
|
||||
mUnderflowStart = (int) Math.max(contentStart, width - getPaddingEnd() - mUnderflowWidth);
|
||||
int visible = 0;
|
||||
int firstUnderflowIndex = -1;
|
||||
for (int i = totalVisible - 1; i >= 0; i--) {
|
||||
StatusIconState state = mLayoutStates.get(i);
|
||||
// Allow room for underflow if we found we need it in onMeasure
|
||||
if (mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth))
|
||||
if ((mNeedsUnderflow && (state.getXTranslation() < (contentStart + mUnderflowWidth)))
|
||||
|| (mShouldRestrictIcons && (visible >= maxVisible))) {
|
||||
firstUnderflowIndex = i;
|
||||
break;
|
||||
|
||||
@@ -374,6 +374,13 @@ public class Clock extends TextView implements
|
||||
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
reloadDimens();
|
||||
}
|
||||
|
||||
private void reloadDimens() {
|
||||
// reset mCachedWidth so the new width would be updated properly when next onMeasure
|
||||
mCachedWidth = -1;
|
||||
|
||||
FontSizeUtils.updateFontSize(this, R.dimen.status_bar_clock_size);
|
||||
setPaddingRelative(
|
||||
mContext.getResources().getDimensionPixelSize(
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.testing.TestableLooper.RunWithLooper
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.StatusBarIconView
|
||||
import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
|
||||
import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
|
||||
import junit.framework.Assert.assertEquals
|
||||
import junit.framework.Assert.assertFalse
|
||||
import junit.framework.Assert.assertTrue
|
||||
@@ -49,7 +51,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
fun calculateWidthFor_oneIcon_widthForOneIcon() {
|
||||
iconContainer.setActualPaddingStart(10f)
|
||||
iconContainer.setActualPaddingEnd(10f)
|
||||
iconContainer.setIconSize(10);
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 1f),
|
||||
/* actual= */ 30f)
|
||||
@@ -59,7 +61,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
fun calculateWidthFor_fourIcons_widthForFourIcons() {
|
||||
iconContainer.setActualPaddingStart(10f)
|
||||
iconContainer.setActualPaddingEnd(10f)
|
||||
iconContainer.setIconSize(10);
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 4f),
|
||||
/* actual= */ 60f)
|
||||
@@ -69,7 +71,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
fun calculateWidthFor_fiveIcons_widthForFourIcons() {
|
||||
iconContainer.setActualPaddingStart(10f)
|
||||
iconContainer.setActualPaddingEnd(10f)
|
||||
iconContainer.setIconSize(10);
|
||||
iconContainer.setIconSize(10)
|
||||
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 5f),
|
||||
/* actual= */ 60f)
|
||||
}
|
||||
@@ -78,7 +80,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
fun calculateIconXTranslations_shortShelfOneIcon_atCorrectXWithoutOverflowDot() {
|
||||
iconContainer.setActualPaddingStart(10f)
|
||||
iconContainer.setActualPaddingEnd(10f)
|
||||
iconContainer.setIconSize(10);
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
val icon = mockStatusBarIcon()
|
||||
iconContainer.addView(icon)
|
||||
@@ -99,7 +101,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
fun calculateIconXTranslations_shortShelfFourIcons_atCorrectXWithoutOverflowDot() {
|
||||
iconContainer.setActualPaddingStart(10f)
|
||||
iconContainer.setActualPaddingEnd(10f)
|
||||
iconContainer.setIconSize(10);
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
val iconOne = mockStatusBarIcon()
|
||||
val iconTwo = mockStatusBarIcon()
|
||||
@@ -128,7 +130,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
fun calculateIconXTranslations_shortShelfFiveIcons_atCorrectXWithOverflowDot() {
|
||||
iconContainer.setActualPaddingStart(10f)
|
||||
iconContainer.setActualPaddingEnd(10f)
|
||||
iconContainer.setIconSize(10);
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
val iconOne = mockStatusBarIcon()
|
||||
val iconTwo = mockStatusBarIcon()
|
||||
@@ -153,6 +155,55 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
assertTrue(iconContainer.areIconsOverflowing())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun calculateIconXTranslations_givenWidthEnoughForThreeIcons_atCorrectXWithoutOverflowDot() {
|
||||
iconContainer.setActualPaddingStart(0f)
|
||||
iconContainer.setActualPaddingEnd(0f)
|
||||
iconContainer.setActualLayoutWidth(30)
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
val iconOne = mockStatusBarIcon()
|
||||
val iconTwo = mockStatusBarIcon()
|
||||
val iconThree = mockStatusBarIcon()
|
||||
|
||||
iconContainer.addView(iconOne)
|
||||
iconContainer.addView(iconTwo)
|
||||
iconContainer.addView(iconThree)
|
||||
assertEquals(3, iconContainer.childCount)
|
||||
|
||||
iconContainer.calculateIconXTranslations()
|
||||
assertEquals(0f, iconContainer.getIconState(iconOne).xTranslation)
|
||||
assertEquals(10f, iconContainer.getIconState(iconTwo).xTranslation)
|
||||
assertEquals(20f, iconContainer.getIconState(iconThree).xTranslation)
|
||||
assertFalse(iconContainer.areIconsOverflowing())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun calculateIconXTranslations_givenWidthNotEnoughForFourIcons_atCorrectXWithOverflowDot() {
|
||||
iconContainer.setActualPaddingStart(0f)
|
||||
iconContainer.setActualPaddingEnd(0f)
|
||||
iconContainer.setActualLayoutWidth(35)
|
||||
iconContainer.setIconSize(10)
|
||||
|
||||
val iconOne = mockStatusBarIcon()
|
||||
val iconTwo = mockStatusBarIcon()
|
||||
val iconThree = mockStatusBarIcon()
|
||||
val iconFour = mockStatusBarIcon()
|
||||
|
||||
iconContainer.addView(iconOne)
|
||||
iconContainer.addView(iconTwo)
|
||||
iconContainer.addView(iconThree)
|
||||
iconContainer.addView(iconFour)
|
||||
assertEquals(4, iconContainer.childCount)
|
||||
|
||||
iconContainer.calculateIconXTranslations()
|
||||
assertEquals(0f, iconContainer.getIconState(iconOne).xTranslation)
|
||||
assertEquals(10f, iconContainer.getIconState(iconTwo).xTranslation)
|
||||
assertEquals(STATE_DOT, iconContainer.getIconState(iconThree).visibleState)
|
||||
assertEquals(STATE_HIDDEN, iconContainer.getIconState(iconFour).visibleState)
|
||||
assertTrue(iconContainer.areIconsOverflowing())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldForceOverflow_appearingAboveSpeedBump_true() {
|
||||
val forceOverflow = iconContainer.shouldForceOverflow(
|
||||
@@ -161,7 +212,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
/* iconAppearAmount= */ 1f,
|
||||
/* maxVisibleIcons= */ 5
|
||||
)
|
||||
assertTrue(forceOverflow);
|
||||
assertTrue(forceOverflow)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -172,7 +223,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
/* iconAppearAmount= */ 0f,
|
||||
/* maxVisibleIcons= */ 5
|
||||
)
|
||||
assertTrue(forceOverflow);
|
||||
assertTrue(forceOverflow)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,7 +234,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
/* iconAppearAmount= */ 0f,
|
||||
/* maxVisibleIcons= */ 5
|
||||
)
|
||||
assertFalse(forceOverflow);
|
||||
assertFalse(forceOverflow)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -209,6 +260,17 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
assertTrue(isOverflowing)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isOverflowing_lastChildXGreaterThanDotX_true() {
|
||||
val isOverflowing = iconContainer.isOverflowing(
|
||||
/* isLastChild= */ true,
|
||||
/* translationX= */ 9f,
|
||||
/* layoutEnd= */ 10f,
|
||||
/* iconSize= */ 2f,
|
||||
)
|
||||
assertTrue(isOverflowing)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
|
||||
val isOverflowing = iconContainer.isOverflowing(
|
||||
@@ -253,7 +315,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
||||
assertTrue(isOverflowing)
|
||||
}
|
||||
|
||||
private fun mockStatusBarIcon() : StatusBarIconView {
|
||||
private fun mockStatusBarIcon(): StatusBarIconView {
|
||||
val iconView = mock(StatusBarIconView::class.java)
|
||||
whenever(iconView.width).thenReturn(10)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user