diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 24da59a378f81..b129321008d83 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -95,8 +95,10 @@
96dp
96dp
-
+
22dip
+
+ 22sp
15dp
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index d053a7a0d0bb3..28f98f4821fa0 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -20,7 +20,7 @@
10dp
- 1dp
+ 1sp
28dp
40dp
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3bd7a0664d5ab..e1e6c99026509 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -121,24 +121,26 @@
0dp
6dp
-
+
+ @*android:dimen/status_bar_icon_size_sp
+
@*android:dimen/status_bar_icon_size
- 2.5dp
+ 2.5sp
- 13.0dp
+ 13.0sp
- 7.8dp
+ so the width of the icon should be 13.0sp * (12.0 / 20.0) -->
+ 7.8sp
-
- 1dp
+ 1sp
14sp
@@ -153,19 +155,26 @@
0dp
- 2dp
+ 2sp
- 2.5dp
+ 2.5sp
+
+ 17sp
- @*android:dimen/status_bar_system_icon_size
+ 13sp
+
+
+ 17sp
+
+ 13sp
- 4dp
+ 4sp
- 0dp
+ 0sp
- 1.0
@@ -335,7 +344,7 @@
8dp
- 0dp
+ 0sp
8dp
@@ -347,10 +356,10 @@
0dp
- 2dp
+ 2sp
- 3dp
+ 3sp
@@ -838,7 +847,7 @@
- 2dp
+ 2sp
@@ -1064,7 +1073,7 @@
4dp
- 16dp
+ 16sp
28dp
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index c3b5db42e08dc..310d23407d5da 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -15,6 +15,8 @@
package com.android.systemui.privacy
import android.content.Context
+import android.content.pm.ActivityInfo
+import android.content.res.Configuration
import android.util.AttributeSet
import android.view.Gravity.CENTER_VERTICAL
import android.view.Gravity.END
@@ -35,6 +37,7 @@ class OngoingPrivacyChip @JvmOverloads constructor(
defStyleRes: Int = 0
) : LaunchableFrameLayout(context, attrs, defStyleAttrs, defStyleRes), BackgroundAnimatableView {
+ private var configuration: Configuration
private var iconMargin = 0
private var iconSize = 0
private var iconColor = 0
@@ -54,6 +57,7 @@ class OngoingPrivacyChip @JvmOverloads constructor(
clipChildren = true
clipToPadding = true
iconsContainer = requireViewById(R.id.icons_container)
+ configuration = Configuration(context.resources.configuration)
updateResources()
}
@@ -102,6 +106,17 @@ class OngoingPrivacyChip @JvmOverloads constructor(
R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
}
+ override fun onConfigurationChanged(newConfig: Configuration?) {
+ super.onConfigurationChanged(newConfig)
+ if (newConfig != null) {
+ val diff = newConfig.diff(configuration)
+ configuration.setTo(newConfig)
+ if (diff.and(ActivityInfo.CONFIG_DENSITY.or(ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+ updateResources()
+ }
+ }
+ }
+
private fun updateResources() {
iconMargin = context.resources
.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_margin)
@@ -110,8 +125,11 @@ class OngoingPrivacyChip @JvmOverloads constructor(
iconColor =
Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
+ val height = context.resources
+ .getDimensionPixelSize(R.dimen.ongoing_appops_chip_height)
val padding = context.resources
.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
+ iconsContainer.layoutParams.height = height
iconsContainer.setPaddingRelative(padding, 0, padding, 0)
iconsContainer.background = context.getDrawable(R.drawable.statusbar_privacy_chip_bg)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 4356a3fb29d80..cff71d2edd238 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -26,6 +26,7 @@ import android.annotation.IntDef;
import android.app.ActivityManager;
import android.app.Notification;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -46,12 +47,14 @@ import android.util.Log;
import android.util.Property;
import android.util.TypedValue;
import android.view.ViewDebug;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Interpolator;
import androidx.core.graphics.ColorUtils;
import com.android.app.animation.Interpolators;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.R;
@@ -131,8 +134,11 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
};
private int mStatusBarIconDrawingSizeIncreased = 1;
- private int mStatusBarIconDrawingSize = 1;
- private int mStatusBarIconSize = 1;
+ @VisibleForTesting int mStatusBarIconDrawingSize = 1;
+
+ @VisibleForTesting int mOriginalStatusBarIconSize = 1;
+ @VisibleForTesting int mNewStatusBarIconSize = 1;
+ @VisibleForTesting float mScaleToFitNewIconSize = 1;
private StatusBarIcon mIcon;
@ViewDebug.ExportedProperty private String mSlot;
private Drawable mNumberBackground;
@@ -142,7 +148,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
private String mNumberText;
private StatusBarNotification mNotification;
private final boolean mBlocked;
- private int mDensity;
+ private Configuration mConfiguration;
private boolean mNightMode;
private float mIconScale = 1.0f;
private final Paint mDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -196,9 +202,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
mNumberPain.setAntiAlias(true);
setNotification(sbn);
setScaleType(ScaleType.CENTER);
- mDensity = context.getResources().getDisplayMetrics().densityDpi;
- Configuration configuration = context.getResources().getConfiguration();
- mNightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+ mConfiguration = new Configuration(context.getResources().getConfiguration());
+ mNightMode = (mConfiguration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
== Configuration.UI_MODE_NIGHT_YES;
initializeDecorColor();
reloadDimens();
@@ -206,7 +211,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
/** Should always be preceded by {@link #reloadDimens()} */
- private void maybeUpdateIconScaleDimens() {
+ @VisibleForTesting
+ public void maybeUpdateIconScaleDimens() {
// We do not resize and scale system icons (on the right), only notification icons (on the
// left).
if (isNotification()) {
@@ -217,22 +223,63 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
private void updateIconScaleForNotifications() {
+ float iconScale;
+ // we need to scale the image size to be same as the original size
+ // (fit mOriginalStatusBarIconSize), then we can scale it with mScaleToFitNewIconSize
+ // to fit mNewStatusBarIconSize
+ float scaleToOriginalDrawingSize = 1.0f;
+ ViewGroup.LayoutParams lp = getLayoutParams();
+ if (getDrawable() != null && (lp != null && lp.width > 0 && lp.height > 0)) {
+ final int iconViewWidth = lp.width;
+ final int iconViewHeight = lp.height;
+ // first we estimate the image exact size when put the drawable in scaled iconView size,
+ // then we can compute the scaleToOriginalDrawingSize to make the image size fit in
+ // mOriginalStatusBarIconSize
+ final int drawableWidth = getDrawable().getIntrinsicWidth();
+ final int drawableHeight = getDrawable().getIntrinsicHeight();
+ float scaleToFitIconView = Math.min(
+ (float) iconViewWidth / drawableWidth,
+ (float) iconViewHeight / drawableHeight);
+ // if the drawable size <= the icon view size, the drawable won't be scaled
+ if (scaleToFitIconView > 1.0f) {
+ scaleToFitIconView = 1.0f;
+ }
+ final float scaledImageWidth = drawableWidth * scaleToFitIconView;
+ final float scaledImageHeight = drawableHeight * scaleToFitIconView;
+ // if the scaled image size <= mOriginalStatusBarIconSize, we don't need to enlarge it
+ scaleToOriginalDrawingSize = Math.min(
+ (float) mOriginalStatusBarIconSize / scaledImageWidth,
+ (float) mOriginalStatusBarIconSize / scaledImageHeight);
+ if (scaleToOriginalDrawingSize > 1.0f) {
+ scaleToOriginalDrawingSize = 1.0f;
+ }
+ }
+ iconScale = scaleToOriginalDrawingSize;
+
final float imageBounds = mIncreasedSize ?
mStatusBarIconDrawingSizeIncreased : mStatusBarIconDrawingSize;
- final int outerBounds = mStatusBarIconSize;
- mIconScale = imageBounds / (float)outerBounds;
+ final int originalOuterBounds = mOriginalStatusBarIconSize;
+ iconScale = iconScale * (imageBounds / (float) originalOuterBounds);
+
+ // scale image to fit new icon size
+ mIconScale = iconScale * mScaleToFitNewIconSize;
+
updatePivot();
}
// Makes sure that all icons are scaled to the same height (15dp). If we cannot get a height
// for the icon, it uses the default SCALE (15f / 17f) which is the old behavior
private void updateIconScaleForSystemIcons() {
+ float iconScale;
float iconHeight = getIconHeight();
if (iconHeight != 0) {
- mIconScale = mSystemIconDesiredHeight / iconHeight;
+ iconScale = mSystemIconDesiredHeight / iconHeight;
} else {
- mIconScale = mSystemIconDefaultScale;
+ iconScale = mSystemIconDefaultScale;
}
+
+ // scale image to fit new icon size
+ mIconScale = iconScale * mScaleToFitNewIconSize;
}
private float getIconHeight() {
@@ -255,12 +302,10 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- int density = newConfig.densityDpi;
- if (density != mDensity) {
- mDensity = density;
- reloadDimens();
- updateDrawable();
- maybeUpdateIconScaleDimens();
+ final int configDiff = newConfig.diff(mConfiguration);
+ mConfiguration.setTo(newConfig);
+ if ((configDiff & (ActivityInfo.CONFIG_DENSITY | ActivityInfo.CONFIG_FONT_SCALE)) != 0) {
+ updateIconDimens();
}
boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
== Configuration.UI_MODE_NIGHT_YES;
@@ -270,11 +315,22 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
}
+ /**
+ * Update the icon dimens and drawable with current resources
+ */
+ public void updateIconDimens() {
+ reloadDimens();
+ updateDrawable();
+ maybeUpdateIconScaleDimens();
+ }
+
private void reloadDimens() {
boolean applyRadius = mDotRadius == mStaticDotRadius;
Resources res = getResources();
mStaticDotRadius = res.getDimensionPixelSize(R.dimen.overflow_dot_radius);
- mStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ mOriginalStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ mNewStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size_sp);
+ mScaleToFitNewIconSize = (float) mNewStatusBarIconSize / mOriginalStatusBarIconSize;
mStatusBarIconDrawingSizeIncreased =
res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
mStatusBarIconDrawingSize =
@@ -482,12 +538,30 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
updateDrawable();
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ if (!isNotification()) {
+ // for system icons, calculated measured width from super is for image drawable real
+ // width (17dp). We may scale the image with font scale, so we also need to scale the
+ // measured width so that scaled measured width and image width would be fit.
+ int measuredWidth = getMeasuredWidth();
+ int measuredHeight = getMeasuredHeight();
+ setMeasuredDimension((int) (measuredWidth * mScaleToFitNewIconSize), measuredHeight);
+ }
+ }
+
@Override
protected void onDraw(Canvas canvas) {
+ // In this method, for width/height division computation we intend to discard the
+ // fractional part as the original behavior.
if (mIconAppearAmount > 0.0f) {
canvas.save();
+ int px = getWidth() / 2;
+ int py = getHeight() / 2;
canvas.scale(mIconScale * mIconAppearAmount, mIconScale * mIconAppearAmount,
- getWidth() / 2, getHeight() / 2);
+ (float) px, (float) py);
super.onDraw(canvas);
canvas.restore();
}
@@ -504,10 +578,15 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
} else {
float fadeOutAmount = mDotAppearAmount - 1.0f;
alpha = alpha * (1.0f - fadeOutAmount);
- radius = NotificationUtils.interpolate(mDotRadius, getWidth() / 4, fadeOutAmount);
+ int end = getWidth() / 4;
+ radius = NotificationUtils.interpolate(mDotRadius, (float) end, fadeOutAmount);
}
mDotPaint.setAlpha((int) (alpha * 255));
- canvas.drawCircle(mStatusBarIconSize / 2, getHeight() / 2, radius, mDotPaint);
+ int cx = mNewStatusBarIconSize / 2;
+ int cy = getHeight() / 2;
+ canvas.drawCircle(
+ (float) cx, (float) cy,
+ radius, mDotPaint);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index fdad101ae0f65..d6f6c2c281de7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -135,7 +135,7 @@ public class StatusBarMobileView extends BaseStatusBarFrameLayout implements Dar
mDotView = new StatusBarIconView(mContext, mSlot, null);
mDotView.setVisibleState(STATE_DOT);
- int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size_sp);
LayoutParams lp = new LayoutParams(width, width);
lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
addView(mDotView, lp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
index decc70d175b86..8d7214d6bd759 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java
@@ -164,7 +164,7 @@ public class StatusBarWifiView extends BaseStatusBarFrameLayout implements DarkR
mDotView = new StatusBarIconView(mContext, mSlot, null);
mDotView.setVisibleState(STATE_DOT);
- int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size_sp);
LayoutParams lp = new LayoutParams(width, width);
lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
addView(mDotView, lp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 2fd244e1357f1..0fde3ab3d19ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -239,7 +239,7 @@ public class NotificationIconAreaController implements
private void reloadDimens(Context context) {
Resources res = context.getResources();
- mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+ mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size_sp);
mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_horizontal_margin);
mAodIconAppearTranslation = res.getDimensionPixelSize(
R.dimen.shelf_appear_translation);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index bef422ce3004f..15ca37a222e52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -339,6 +339,7 @@ public class NotificationIconContainer extends ViewGroup {
}
}
if (child instanceof StatusBarIconView) {
+ ((StatusBarIconView) child).updateIconDimens();
((StatusBarIconView) child).setDozing(mDozing, false, 0);
}
}
@@ -537,9 +538,10 @@ public class NotificationIconContainer extends ViewGroup {
IconState iconState = mIconStates.get(mIsolatedIcon);
if (iconState != null) {
// Most of the time the icon isn't yet added when this is called but only happening
- // later
- iconState.setXTranslation(mIsolatedIconLocation.left - mAbsolutePosition[0]
- - (1 - mIsolatedIcon.getIconScale()) * mIsolatedIcon.getWidth() / 2.0f);
+ // later. The isolated icon position left should equal to the mIsolatedIconLocation
+ // to ensure the icon be put at the center of the HUN icon placeholder,
+ // {@See HeadsUpAppearanceController#updateIsolatedIconLocation}.
+ iconState.setXTranslation(mIsolatedIconLocation.left - mAbsolutePosition[0]);
iconState.visibleState = StatusBarIconView.STATE_ICON;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index b14fe90cd1b3b..59583ddf3e34a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -370,7 +370,7 @@ public interface StatusBarIconController {
private final MobileIconsViewModel mMobileIconsViewModel;
protected final Context mContext;
- protected final int mIconSize;
+ protected int mIconSize;
// Whether or not these icons show up in dumpsys
protected boolean mShouldLog = false;
private StatusBarIconController mController;
@@ -395,10 +395,10 @@ public interface StatusBarIconController {
mStatusBarPipelineFlags = statusBarPipelineFlags;
mMobileContextProvider = mobileContextProvider;
mContext = group.getContext();
- mIconSize = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_icon_size);
mLocation = location;
+ reloadDimens();
+
if (statusBarPipelineFlags.runNewMobileIconsBackend()) {
// This starts the flow for the new pipeline, and will notify us of changes if
// {@link StatusBarPipelineFlags#useNewMobileIcons} is also true.
@@ -609,13 +609,9 @@ public interface StatusBarIconController {
mGroup.removeAllViews();
}
- protected void onDensityOrFontScaleChanged() {
- for (int i = 0; i < mGroup.getChildCount(); i++) {
- View child = mGroup.getChildAt(i);
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
- child.setLayoutParams(lp);
- }
+ protected void reloadDimens() {
+ mIconSize = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_icon_size_sp);
}
private void setHeightAndCenter(ImageView imageView, int height) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 3a184239ac436..80d5651a65dc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -109,6 +109,7 @@ public class StatusBarIconControllerImpl implements Tunable,
}
group.setController(this);
+ group.reloadDimens();
mIconGroups.add(group);
List allSlots = mStatusBarIconList.getSlots();
for (int i = 0; i < allSlots.size(); i++) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 604b1f5008db3..3074abec860d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -103,7 +103,7 @@ public class StatusIconContainer extends AlphaOptimizedLinearLayout {
private void initDimens() {
// This is the same value that StatusBarIconView uses
mIconDotFrameWidth = getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_icon_size);
+ com.android.internal.R.dimen.status_bar_icon_size_sp);
mDotPadding = getResources().getDimensionPixelSize(R.dimen.overflow_icon_dot_padding);
mIconSpacing = getResources().getDimensionPixelSize(R.dimen.status_bar_system_icon_spacing);
int radius = getResources().getDimensionPixelSize(R.dimen.overflow_dot_radius);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
index 1a1340484bfc3..83738544ee84d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarView.kt
@@ -118,7 +118,7 @@ open class ModernStatusBarView(context: Context, attrs: AttributeSet?) :
it.visibleState = STATE_DOT
}
- val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size)
+ val width = mContext.resources.getDimensionPixelSize(R.dimen.status_bar_icon_size_sp)
val lp = LayoutParams(width, width)
lp.gravity = Gravity.CENTER_VERTICAL or Gravity.START
addView(dotView, lp)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 1b1f4e41f200d..8d016e30c0c12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -45,6 +45,7 @@ import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
+import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -65,6 +66,8 @@ import org.mockito.ArgumentMatcher;
@RunWith(AndroidJUnit4.class)
public class StatusBarIconViewTest extends SysuiTestCase {
+ private static final int TEST_STATUS_BAR_HEIGHT = 150;
+
@Rule
public ExpectedException mThrown = ExpectedException.none();
@@ -184,4 +187,218 @@ public class StatusBarIconViewTest extends SysuiTestCase {
// no crash, good
}
+
+ @Test
+ public void testUpdateIconScale_constrainedDrawableSizeLessThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // the icon view layout size would be 60x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, dpIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 50x50. When put the drawable into iconView whose
+ // layout size is 60x150, the drawable size would not be constrained and thus keep 50x50
+ setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN both the constrained drawable width/height are less than dpIconSize,
+ // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+ float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+ assertEquals(scaleToFitDrawingSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_constrainedDrawableHeightLargerThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // the icon view layout size would be 60x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, dpIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 50x100. When put the drawable into iconView whose
+ // layout size is 60x150, the drawable size would not be constrained and thus keep 50x100
+ setIconDrawableWithSize(/* width= */ 50, /* height= */ 100);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN constrained drawable larger side length 100 >= dpIconSize
+ // THEN the icon is scaled down from larger side length 100 to ensure both side
+ // length fit in dpDrawingSize.
+ float scaleToFitDrawingSize = (float) dpDrawingSize / 100;
+ assertEquals(scaleToFitDrawingSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_constrainedDrawableWidthLargerThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // the icon view layout size would be 60x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, dpIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 100x50. When put the drawable into iconView whose
+ // layout size is 60x150, the drawable size would be constrained to 60x30
+ setIconDrawableWithSize(/* width= */ 100, /* height= */ 50);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN constrained drawable larger side length 60 >= dpIconSize
+ // THEN the icon is scaled down from larger side length 60 to ensure both side
+ // length fit in dpDrawingSize.
+ float scaleToFitDrawingSize = (float) dpDrawingSize / 60;
+ assertEquals(scaleToFitDrawingSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_smallerFontAndConstrainedDrawableSizeLessThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // smaller font scaling causes the spIconSize < dpIconSize
+ int spIconSize = 40;
+ // the icon view layout size would be 40x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 50x50. When put the drawable into iconView whose
+ // layout size is 40x150, the drawable size would be constrained to 40x40
+ setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN both the constrained drawable width/height are less than dpIconSize,
+ // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+ float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+ // THEN the scaled icon should be scaled down further to fit spIconSize
+ float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+ assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_smallerFontAndConstrainedDrawableHeightLargerThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // smaller font scaling causes the spIconSize < dpIconSize
+ int spIconSize = 40;
+ // the icon view layout size would be 40x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 50x100. When put the drawable into iconView whose
+ // layout size is 40x150, the drawable size would be constrained to 40x80
+ setIconDrawableWithSize(/* width= */ 50, /* height= */ 100);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN constrained drawable larger side length 80 >= dpIconSize
+ // THEN the icon is scaled down from larger side length 80 to ensure both side
+ // length fit in dpDrawingSize.
+ float scaleToFitDrawingSize = (float) dpDrawingSize / 80;
+ // THEN the scaled icon should be scaled down further to fit spIconSize
+ float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+ assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_largerFontAndConstrainedDrawableSizeLessThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // larger font scaling causes the spIconSize > dpIconSize
+ int spIconSize = 80;
+ // the icon view layout size would be 80x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 50x50. When put the drawable into iconView whose
+ // layout size is 80x150, the drawable size would not be constrained and thus keep 50x50
+ setIconDrawableWithSize(/* width= */ 50, /* height= */ 50);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN both the constrained drawable width/height are less than dpIconSize,
+ // THEN the icon is scaled down from dpIconSize to fit the dpDrawingSize
+ float scaleToFitDrawingSize = (float) dpDrawingSize / dpIconSize;
+ // THEN the scaled icon should be scaled up to fit spIconSize
+ float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+ assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_largerFontAndConstrainedDrawableHeightLargerThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // larger font scaling causes the spIconSize > dpIconSize
+ int spIconSize = 80;
+ // the icon view layout size would be 80x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 50x100. When put the drawable into iconView whose
+ // layout size is 80x150, the drawable size would not be constrained and thus keep 50x100
+ setIconDrawableWithSize(/* width= */ 50, /* height= */ 100);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN constrained drawable larger side length 100 >= dpIconSize
+ // THEN the icon is scaled down from larger side length 100 to ensure both side
+ // length fit in dpDrawingSize.
+ float scaleToFitDrawingSize = (float) dpDrawingSize / 100;
+ // THEN the scaled icon should be scaled up to fit spIconSize
+ float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+ assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize, mIconView.getIconScale(), 0.01f);
+ }
+
+ @Test
+ public void testUpdateIconScale_largerFontAndConstrainedDrawableWidthLargerThanDpIconSize() {
+ int dpIconSize = 60;
+ int dpDrawingSize = 30;
+ // larger font scaling causes the spIconSize > dpIconSize
+ int spIconSize = 80;
+ // the icon view layout size would be 80x150
+ // (the height is always 150 due to TEST_STATUS_BAR_HEIGHT)
+ setUpIconView(dpIconSize, dpDrawingSize, spIconSize);
+ mIconView.setNotification(mock(StatusBarNotification.class));
+ // the raw drawable size is 100x50. When put the drawable into iconView whose
+ // layout size is 80x150, the drawable size would not be constrained and thus keep 80x40
+ setIconDrawableWithSize(/* width= */ 100, /* height= */ 50);
+ mIconView.maybeUpdateIconScaleDimens();
+
+ // WHEN constrained drawable larger side length 80 >= dpIconSize
+ // THEN the icon is scaled down from larger side length 80 to ensure both side
+ // length fit in dpDrawingSize.
+ float scaleToFitDrawingSize = (float) dpDrawingSize / 80;
+ // THEN the scaled icon should be scaled up to fit spIconSize
+ float scaleToFitSpIconSize = (float) spIconSize / dpIconSize;
+ assertEquals(scaleToFitDrawingSize * scaleToFitSpIconSize,
+ mIconView.getIconScale(), 0.01f);
+ }
+
+ /**
+ * Setup iconView dimens for testing. The result icon view layout width would
+ * be spIconSize and height would be 150.
+ *
+ * @param dpIconSize corresponding to status_bar_icon_size
+ * @param dpDrawingSize corresponding to status_bar_icon_drawing_size
+ * @param spIconSize corresponding to status_bar_icon_size_sp under different font scaling
+ */
+ private void setUpIconView(int dpIconSize, int dpDrawingSize, int spIconSize) {
+ mIconView.setIncreasedSize(false);
+ mIconView.mOriginalStatusBarIconSize = dpIconSize;
+ mIconView.mStatusBarIconDrawingSize = dpDrawingSize;
+
+ mIconView.mNewStatusBarIconSize = spIconSize;
+ mIconView.mScaleToFitNewIconSize = (float) spIconSize / dpIconSize;
+
+ // the layout width would be spIconSize + 2 * iconPadding, and we assume iconPadding
+ // is 0 here.
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(spIconSize, TEST_STATUS_BAR_HEIGHT);
+ mIconView.setLayoutParams(lp);
+ }
+
+ private void setIconDrawableWithSize(int width, int height) {
+ Bitmap bitmap = Bitmap.createBitmap(
+ width, height, Bitmap.Config.ARGB_8888);
+ Icon icon = Icon.createWithBitmap(bitmap);
+ mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+ icon, 0, 0, "");
+ // Since we only want to verify icon scale logic here, we directly use
+ // {@link StatusBarIconView#setImageDrawable(Drawable)} to set the image drawable
+ // to iconView instead of call {@link StatusBarIconView#set(StatusBarIcon)}. It's to prevent
+ // the icon drawable size being scaled down when internally calling
+ // {@link StatusBarIconView#getIcon(Context,Context,StatusBarIcon)}.
+ mIconView.setImageDrawable(icon.loadDrawable(mContext));
+ }
}