Merge "fix(non linear font scaling)!: fix QS text being cut off when 200% font scaling" into udc-dev am: 0acac4d370
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23087397
Change-Id: I4c215a59d7a72a895fc6fd6574599f3c43197528
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 46724ad..d889979 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -24,6 +24,7 @@
import android.widget.LinearLayout;
import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTile.SignalState;
@@ -198,13 +199,23 @@
@Override
public boolean updateResources() {
- mCellHeightResId = R.dimen.qs_quick_tile_size;
+ mResourceCellHeightResId = R.dimen.qs_quick_tile_size;
boolean b = super.updateResources();
mMaxAllowedRows = getResources().getInteger(R.integer.quick_qs_panel_max_rows);
return b;
}
@Override
+ protected void estimateCellHeight() {
+ FontSizeUtils.updateFontSize(mTempTextView, R.dimen.qs_tile_text_size);
+ int unspecifiedSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ mTempTextView.measure(unspecifiedSpec, unspecifiedSpec);
+ int padding = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_padding);
+ // the QQS only have 1 label
+ mEstimatedCellHeight = mTempTextView.getMeasuredHeight() + padding * 2;
+ }
+
+ @Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateResources();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 269a158..19bf018 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -9,10 +9,12 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.TextView;
import androidx.annotation.Nullable;
import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.qs.QSPanel.QSTileLayout;
import com.android.systemui.qs.QSPanelControllerBase.TileRecord;
@@ -29,9 +31,10 @@
protected int mColumns;
protected int mCellWidth;
- protected int mCellHeightResId = R.dimen.qs_tile_height;
+ protected int mResourceCellHeightResId = R.dimen.qs_tile_height;
+ protected int mResourceCellHeight;
+ protected int mEstimatedCellHeight;
protected int mCellHeight;
- protected int mMaxCellHeight;
protected int mCellMarginHorizontal;
protected int mCellMarginVertical;
protected int mSidePadding;
@@ -49,6 +52,8 @@
private float mSquishinessFraction = 1f;
protected int mLastTileBottom;
+ protected TextView mTempTextView;
+
public TileLayout(Context context) {
this(context, null);
}
@@ -57,6 +62,7 @@
super(context, attrs);
mLessRows = ((Settings.System.getInt(context.getContentResolver(), "qs_less_rows", 0) != 0)
|| useQsMediaPlayer(context));
+ mTempTextView = new TextView(context);
updateResources();
}
@@ -120,14 +126,19 @@
}
public boolean updateResources() {
- final Resources res = mContext.getResources();
+ Resources res = getResources();
mResourceColumns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns));
- mMaxCellHeight = mContext.getResources().getDimensionPixelSize(mCellHeightResId);
+ mResourceCellHeight = res.getDimensionPixelSize(mResourceCellHeightResId);
mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal);
mSidePadding = useSidePadding() ? mCellMarginHorizontal / 2 : 0;
mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
mMaxAllowedRows = Math.max(1, getResources().getInteger(R.integer.quick_settings_max_rows));
- if (mLessRows) mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1);
+ if (mLessRows) {
+ mMaxAllowedRows = Math.max(mMinRows, mMaxAllowedRows - 1);
+ }
+ // update estimated cell height under current font scaling
+ mTempTextView.dispatchConfigurationChanged(mContext.getResources().getConfiguration());
+ estimateCellHeight();
if (updateColumns()) {
requestLayout();
return true;
@@ -211,8 +222,23 @@
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
+ // Estimate the height for the tile with 2 labels (general case) under current font scaling.
+ protected void estimateCellHeight() {
+ FontSizeUtils.updateFontSize(mTempTextView, R.dimen.qs_tile_text_size);
+ int unspecifiedSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ mTempTextView.measure(unspecifiedSpec, unspecifiedSpec);
+ int padding = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_padding);
+ mEstimatedCellHeight = mTempTextView.getMeasuredHeight() * 2 + padding * 2;
+ }
+
protected int getCellHeight() {
- return mMaxCellHeight;
+ // Compare estimated height with resource height and return the larger one.
+ // If estimated height > resource height, it means the resource height is not enough
+ // for the tile content under current font scaling. Therefore, we need to use the estimated
+ // height to have a full tile content view.
+ // If estimated height <= resource height, we can use the resource height for tile to keep
+ // the same UI as original behavior.
+ return Math.max(mResourceCellHeight, mEstimatedCellHeight);
}
private void layoutTileRecords(int numRecords, boolean forLayout) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
index 35c8cc7..8789253 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/TileLayoutTest.java
@@ -28,8 +28,11 @@
import static org.mockito.Mockito.verify;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.test.runner.AndroidJUnit4;
@@ -48,6 +51,7 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class TileLayoutTest extends SysuiTestCase {
private Resources mResources;
private int mLayoutSizeForOneTile;
@@ -228,4 +232,53 @@
assertEquals(false, mTileLayout.updateResources());
}
+
+ @Test
+ public void fontScalingChanged_updateResources_cellHeightEnoughForTileContent() {
+ final float originalFontScale = mContext.getResources().getConfiguration().fontScale;
+ float[] testScales = {0.8f, 1.0f, 1.4f, 1.6f, 2.0f};
+ for (float scale: testScales) {
+ changeFontScaling_updateResources_cellHeightEnoughForTileContent(scale);
+ }
+
+ changeFontScaling(originalFontScale);
+ }
+
+ private void changeFontScaling_updateResources_cellHeightEnoughForTileContent(float scale) {
+ changeFontScaling(scale);
+
+ QSPanelControllerBase.TileRecord tileRecord = createTileRecord();
+ mTileLayout.addTile(tileRecord);
+
+ FakeTileView tileView = new FakeTileView(mContext);
+ QSTile.State state = new QSTile.State();
+ state.label = "TEST LABEL";
+ state.secondaryLabel = "TEST SECONDARY LABEL";
+ tileView.changeState(state);
+
+ mTileLayout.updateResources();
+
+ int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+ tileView.measure(spec, spec);
+ assertTrue(mTileLayout.getCellHeight() >= tileView.getMeasuredHeight());
+
+ mTileLayout.removeTile(tileRecord);
+ }
+
+ private static class FakeTileView extends QSTileViewImpl {
+ FakeTileView(Context context) {
+ super(context, new QSIconViewImpl(context), /* collapsed= */ false);
+ }
+
+ void changeState(QSTile.State state) {
+ handleStateChanged(state);
+ }
+ }
+
+ private void changeFontScaling(float scale) {
+ Configuration configuration = new Configuration(mContext.getResources().getConfiguration());
+ configuration.fontScale = scale;
+ // updateConfiguration could help update on both resource configuration and displayMetrics
+ mContext.getResources().updateConfiguration(configuration, null, null);
+ }
}