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) }
|
lastInsets?.let { updateConstraintsForInsets(header, it) }
|
||||||
updateResources()
|
updateResources()
|
||||||
updateCarrierGroupPadding()
|
updateCarrierGroupPadding()
|
||||||
|
clock.onDensityOrFontScaleChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -448,9 +448,14 @@ public class NotificationIconContainer extends ViewGroup {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean isOverflowing(boolean isLastChild, float translationX, float layoutEnd,
|
boolean isOverflowing(boolean isLastChild, float translationX, float layoutEnd,
|
||||||
float iconSize) {
|
float iconSize) {
|
||||||
// Layout end, as used here, does not include padding end.
|
if (isLastChild) {
|
||||||
final float overflowX = isLastChild ? layoutEnd : layoutEnd - iconSize;
|
return translationX + iconSize > layoutEnd;
|
||||||
return translationX >= overflowX;
|
} 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.
|
// First icon to overflow.
|
||||||
if (firstOverflowIndex == -1 && isOverflowing) {
|
if (firstOverflowIndex == -1 && isOverflowing) {
|
||||||
firstOverflowIndex = i;
|
firstOverflowIndex = i;
|
||||||
mVisualOverflowStart = layoutEnd - mIconSize;
|
mVisualOverflowStart = translationX;
|
||||||
if (forceOverflow || mIsStaticLayout) {
|
|
||||||
mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
final float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
|
final float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
|
||||||
? ((StatusBarIconView) view).getIconScaleIncreased()
|
? ((StatusBarIconView) view).getIconScaleIncreased()
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
|
|||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
@@ -73,13 +75,16 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
|||||||
// Any ignored icon will never be added as a child
|
// Any ignored icon will never be added as a child
|
||||||
private ArrayList<String> mIgnoredSlots = new ArrayList<>();
|
private ArrayList<String> mIgnoredSlots = new ArrayList<>();
|
||||||
|
|
||||||
|
private Configuration mConfiguration;
|
||||||
|
|
||||||
public StatusIconContainer(Context context) {
|
public StatusIconContainer(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusIconContainer(Context context, AttributeSet attrs) {
|
public StatusIconContainer(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
initDimens();
|
mConfiguration = new Configuration(context.getResources().getConfiguration());
|
||||||
|
reloadDimens();
|
||||||
setWillNotDraw(!DEBUG_OVERFLOW);
|
setWillNotDraw(!DEBUG_OVERFLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +105,7 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
|||||||
return mShouldRestrictIcons;
|
return mShouldRestrictIcons;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDimens() {
|
private void reloadDimens() {
|
||||||
// This is the same value that StatusBarIconView uses
|
// This is the same value that StatusBarIconView uses
|
||||||
mIconDotFrameWidth = getResources().getDimensionPixelSize(
|
mIconDotFrameWidth = getResources().getDimensionPixelSize(
|
||||||
com.android.internal.R.dimen.status_bar_icon_size_sp);
|
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);
|
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
|
* 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
|
* @param slotName name of the icon as it exists in
|
||||||
@@ -342,13 +357,17 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
|
|||||||
int totalVisible = mLayoutStates.size();
|
int totalVisible = mLayoutStates.size();
|
||||||
int maxVisible = totalVisible <= MAX_ICONS ? MAX_ICONS : MAX_ICONS - 1;
|
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 visible = 0;
|
||||||
int firstUnderflowIndex = -1;
|
int firstUnderflowIndex = -1;
|
||||||
for (int i = totalVisible - 1; i >= 0; i--) {
|
for (int i = totalVisible - 1; i >= 0; i--) {
|
||||||
StatusIconState state = mLayoutStates.get(i);
|
StatusIconState state = mLayoutStates.get(i);
|
||||||
// Allow room for underflow if we found we need it in onMeasure
|
// 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))) {
|
|| (mShouldRestrictIcons && (visible >= maxVisible))) {
|
||||||
firstUnderflowIndex = i;
|
firstUnderflowIndex = i;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -374,6 +374,13 @@ public class Clock extends TextView implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDensityOrFontScaleChanged() {
|
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);
|
FontSizeUtils.updateFontSize(this, R.dimen.status_bar_clock_size);
|
||||||
setPaddingRelative(
|
setPaddingRelative(
|
||||||
mContext.getResources().getDimensionPixelSize(
|
mContext.getResources().getDimensionPixelSize(
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import android.testing.TestableLooper.RunWithLooper
|
|||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.statusbar.StatusBarIconView
|
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.assertEquals
|
||||||
import junit.framework.Assert.assertFalse
|
import junit.framework.Assert.assertFalse
|
||||||
import junit.framework.Assert.assertTrue
|
import junit.framework.Assert.assertTrue
|
||||||
@@ -49,7 +51,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
fun calculateWidthFor_oneIcon_widthForOneIcon() {
|
fun calculateWidthFor_oneIcon_widthForOneIcon() {
|
||||||
iconContainer.setActualPaddingStart(10f)
|
iconContainer.setActualPaddingStart(10f)
|
||||||
iconContainer.setActualPaddingEnd(10f)
|
iconContainer.setActualPaddingEnd(10f)
|
||||||
iconContainer.setIconSize(10);
|
iconContainer.setIconSize(10)
|
||||||
|
|
||||||
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 1f),
|
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 1f),
|
||||||
/* actual= */ 30f)
|
/* actual= */ 30f)
|
||||||
@@ -59,7 +61,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
fun calculateWidthFor_fourIcons_widthForFourIcons() {
|
fun calculateWidthFor_fourIcons_widthForFourIcons() {
|
||||||
iconContainer.setActualPaddingStart(10f)
|
iconContainer.setActualPaddingStart(10f)
|
||||||
iconContainer.setActualPaddingEnd(10f)
|
iconContainer.setActualPaddingEnd(10f)
|
||||||
iconContainer.setIconSize(10);
|
iconContainer.setIconSize(10)
|
||||||
|
|
||||||
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 4f),
|
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 4f),
|
||||||
/* actual= */ 60f)
|
/* actual= */ 60f)
|
||||||
@@ -69,7 +71,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
fun calculateWidthFor_fiveIcons_widthForFourIcons() {
|
fun calculateWidthFor_fiveIcons_widthForFourIcons() {
|
||||||
iconContainer.setActualPaddingStart(10f)
|
iconContainer.setActualPaddingStart(10f)
|
||||||
iconContainer.setActualPaddingEnd(10f)
|
iconContainer.setActualPaddingEnd(10f)
|
||||||
iconContainer.setIconSize(10);
|
iconContainer.setIconSize(10)
|
||||||
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 5f),
|
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 5f),
|
||||||
/* actual= */ 60f)
|
/* actual= */ 60f)
|
||||||
}
|
}
|
||||||
@@ -78,7 +80,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
fun calculateIconXTranslations_shortShelfOneIcon_atCorrectXWithoutOverflowDot() {
|
fun calculateIconXTranslations_shortShelfOneIcon_atCorrectXWithoutOverflowDot() {
|
||||||
iconContainer.setActualPaddingStart(10f)
|
iconContainer.setActualPaddingStart(10f)
|
||||||
iconContainer.setActualPaddingEnd(10f)
|
iconContainer.setActualPaddingEnd(10f)
|
||||||
iconContainer.setIconSize(10);
|
iconContainer.setIconSize(10)
|
||||||
|
|
||||||
val icon = mockStatusBarIcon()
|
val icon = mockStatusBarIcon()
|
||||||
iconContainer.addView(icon)
|
iconContainer.addView(icon)
|
||||||
@@ -99,7 +101,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
fun calculateIconXTranslations_shortShelfFourIcons_atCorrectXWithoutOverflowDot() {
|
fun calculateIconXTranslations_shortShelfFourIcons_atCorrectXWithoutOverflowDot() {
|
||||||
iconContainer.setActualPaddingStart(10f)
|
iconContainer.setActualPaddingStart(10f)
|
||||||
iconContainer.setActualPaddingEnd(10f)
|
iconContainer.setActualPaddingEnd(10f)
|
||||||
iconContainer.setIconSize(10);
|
iconContainer.setIconSize(10)
|
||||||
|
|
||||||
val iconOne = mockStatusBarIcon()
|
val iconOne = mockStatusBarIcon()
|
||||||
val iconTwo = mockStatusBarIcon()
|
val iconTwo = mockStatusBarIcon()
|
||||||
@@ -128,7 +130,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
fun calculateIconXTranslations_shortShelfFiveIcons_atCorrectXWithOverflowDot() {
|
fun calculateIconXTranslations_shortShelfFiveIcons_atCorrectXWithOverflowDot() {
|
||||||
iconContainer.setActualPaddingStart(10f)
|
iconContainer.setActualPaddingStart(10f)
|
||||||
iconContainer.setActualPaddingEnd(10f)
|
iconContainer.setActualPaddingEnd(10f)
|
||||||
iconContainer.setIconSize(10);
|
iconContainer.setIconSize(10)
|
||||||
|
|
||||||
val iconOne = mockStatusBarIcon()
|
val iconOne = mockStatusBarIcon()
|
||||||
val iconTwo = mockStatusBarIcon()
|
val iconTwo = mockStatusBarIcon()
|
||||||
@@ -153,6 +155,55 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
assertTrue(iconContainer.areIconsOverflowing())
|
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
|
@Test
|
||||||
fun shouldForceOverflow_appearingAboveSpeedBump_true() {
|
fun shouldForceOverflow_appearingAboveSpeedBump_true() {
|
||||||
val forceOverflow = iconContainer.shouldForceOverflow(
|
val forceOverflow = iconContainer.shouldForceOverflow(
|
||||||
@@ -161,7 +212,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
/* iconAppearAmount= */ 1f,
|
/* iconAppearAmount= */ 1f,
|
||||||
/* maxVisibleIcons= */ 5
|
/* maxVisibleIcons= */ 5
|
||||||
)
|
)
|
||||||
assertTrue(forceOverflow);
|
assertTrue(forceOverflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -172,7 +223,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
/* iconAppearAmount= */ 0f,
|
/* iconAppearAmount= */ 0f,
|
||||||
/* maxVisibleIcons= */ 5
|
/* maxVisibleIcons= */ 5
|
||||||
)
|
)
|
||||||
assertTrue(forceOverflow);
|
assertTrue(forceOverflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -183,7 +234,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
/* iconAppearAmount= */ 0f,
|
/* iconAppearAmount= */ 0f,
|
||||||
/* maxVisibleIcons= */ 5
|
/* maxVisibleIcons= */ 5
|
||||||
)
|
)
|
||||||
assertFalse(forceOverflow);
|
assertFalse(forceOverflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -209,6 +260,17 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
assertTrue(isOverflowing)
|
assertTrue(isOverflowing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isOverflowing_lastChildXGreaterThanDotX_true() {
|
||||||
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
|
/* isLastChild= */ true,
|
||||||
|
/* translationX= */ 9f,
|
||||||
|
/* layoutEnd= */ 10f,
|
||||||
|
/* iconSize= */ 2f,
|
||||||
|
)
|
||||||
|
assertTrue(isOverflowing)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
|
fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
|
||||||
val isOverflowing = iconContainer.isOverflowing(
|
val isOverflowing = iconContainer.isOverflowing(
|
||||||
@@ -253,7 +315,7 @@ class NotificationIconContainerTest : SysuiTestCase() {
|
|||||||
assertTrue(isOverflowing)
|
assertTrue(isOverflowing)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mockStatusBarIcon() : StatusBarIconView {
|
private fun mockStatusBarIcon(): StatusBarIconView {
|
||||||
val iconView = mock(StatusBarIconView::class.java)
|
val iconView = mock(StatusBarIconView::class.java)
|
||||||
whenever(iconView.width).thenReturn(10)
|
whenever(iconView.width).thenReturn(10)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user