Merge "fix(non linear font scaling)!: fix QS text being cut off when 200% font scaling" into udc-dev

This commit is contained in:
Roy Chou
2023-05-12 00:59:38 +00:00
committed by Android (Google) Code Review
3 changed files with 97 additions and 7 deletions

View File

@@ -24,6 +24,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
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,12 +199,22 @@ public class QuickQSPanel extends QSPanel {
@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);

View File

@@ -9,10 +9,12 @@ import android.util.AttributeSet;
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 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
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 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
private float mSquishinessFraction = 1f;
protected int mLastTileBottom;
protected TextView mTempTextView;
public TileLayout(Context context) {
this(context, null);
}
@@ -57,6 +62,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
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 class TileLayout extends ViewGroup implements QSTileLayout {
}
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 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
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) {

View File

@@ -28,8 +28,11 @@ import static org.mockito.Mockito.times;
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 @@ import org.mockito.Mockito;
@SmallTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class TileLayoutTest extends SysuiTestCase {
private Resources mResources;
private int mLayoutSizeForOneTile;
@@ -228,4 +232,53 @@ public class TileLayoutTest extends SysuiTestCase {
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);
}
}