diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java index f82474a8e8..1440498e15 100644 --- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -36,6 +36,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.allapps.FloatingHeaderRow; import com.android.launcher3.allapps.FloatingHeaderView; import com.android.launcher3.anim.AlphaUpdateListener; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.keyboard.FocusIndicatorHelper; import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper; import com.android.launcher3.model.data.ItemInfo; @@ -126,6 +127,10 @@ public class PredictionRowView int verticalPadding = getResources().getDimensionPixelSize( R.dimen.all_apps_predicted_icon_vertical_padding); int totalHeight = iconHeight + iconPadding + textHeight + verticalPadding * 2; + if (FeatureFlags.enableTwolineAllapps()) { + // Add extra textHeight to the existing total height. + totalHeight += textHeight; + } return getVisibility() == GONE ? 0 : totalHeight + getPaddingTop() + getPaddingBottom(); } diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index bd004e91a5..ab9836f59e 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -16,6 +16,7 @@ package com.android.launcher3; +import static android.text.Layout.Alignment.ALIGN_NORMAL; import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2; import static com.android.launcher3.config.FeatureFlags.ENABLE_ICON_LABEL_AUTO_SCALING; import static com.android.launcher3.config.FeatureFlags.enableCursorHoverStates; @@ -39,6 +40,7 @@ import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.icu.text.MessageFormat; +import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; @@ -148,6 +150,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, private final MultiTranslateDelegate mTranslateDelegate = new MultiTranslateDelegate(this); private final ActivityContext mActivity; private FastBitmapDrawable mIcon; + private DeviceProfile mDeviceProfile; private boolean mCenterVertically; protected int mDisplay; @@ -206,35 +209,35 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false); mIsRtl = (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); - DeviceProfile grid = mActivity.getDeviceProfile(); + mDeviceProfile = mActivity.getDeviceProfile(); mDisplay = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE); final int defaultIconSize; if (mDisplay == DISPLAY_WORKSPACE) { - setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx); - setCompoundDrawablePadding(grid.iconDrawablePaddingPx); - defaultIconSize = grid.iconSizePx; - setCenterVertically(grid.iconCenterVertically); + setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.iconTextSizePx); + setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx); + defaultIconSize = mDeviceProfile.iconSizePx; + setCenterVertically(mDeviceProfile.iconCenterVertically); } else if (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW || mDisplay == DISPLAY_SEARCH_RESULT_APP_ROW) { - setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx); - setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx); - defaultIconSize = grid.allAppsIconSizePx; + setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.allAppsIconTextSizePx); + setCompoundDrawablePadding(mDeviceProfile.allAppsIconDrawablePaddingPx); + defaultIconSize = mDeviceProfile.allAppsIconSizePx; } else if (mDisplay == DISPLAY_FOLDER) { - setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.folderChildTextSizePx); - setCompoundDrawablePadding(grid.folderChildDrawablePaddingPx); - defaultIconSize = grid.folderChildIconSizePx; + setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.folderChildTextSizePx); + setCompoundDrawablePadding(mDeviceProfile.folderChildDrawablePaddingPx); + defaultIconSize = mDeviceProfile.folderChildIconSizePx; } else if (mDisplay == DISPLAY_SEARCH_RESULT) { - setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx); + setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.allAppsIconTextSizePx); defaultIconSize = getResources().getDimensionPixelSize(R.dimen.search_row_icon_size); } else if (mDisplay == DISPLAY_SEARCH_RESULT_SMALL) { defaultIconSize = getResources().getDimensionPixelSize( R.dimen.search_row_small_icon_size); } else if (mDisplay == DISPLAY_TASKBAR) { - defaultIconSize = grid.iconSizePx; + defaultIconSize = mDeviceProfile.iconSizePx; } else { // widget_selection or shortcut_popup - defaultIconSize = grid.iconSizePx; + defaultIconSize = mDeviceProfile.iconSizePx; } mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false); @@ -274,8 +277,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mDotParams.scale = 0f; mForceHideDot = false; setBackground(null); - if (Flags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() - || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) { + if (FeatureFlags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) { setMaxLines(1); } @@ -407,8 +409,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, * Only if actual text can be displayed in two line, the {@code true} value will be effective. */ protected boolean shouldUseTwoLine() { - return ((Flags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) - && mDisplay == DISPLAY_ALL_APPS) + return ((FeatureFlags.enableTwolineAllapps()) + && (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW)) || (FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get() && mDisplay == DISPLAY_SEARCH_RESULT); } @@ -691,21 +693,28 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int height = MeasureSpec.getSize(heightMeasureSpec); if (mCenterVertically) { Paint.FontMetrics fm = getPaint().getFontMetrics(); int cellHeightPx = mIconSize + getCompoundDrawablePadding() + (int) Math.ceil(fm.bottom - fm.top); - int height = MeasureSpec.getSize(heightMeasureSpec); setPadding(getPaddingLeft(), (height - cellHeightPx) / 2, getPaddingRight(), getPaddingBottom()); } // Only apply two line for all_apps and device search only if necessary. if (shouldUseTwoLine() && (mLastOriginalText != null)) { + int allowedVerticalSpace = height - getPaddingTop() - getPaddingBottom() + - mDeviceProfile.allAppsIconSizePx + - mDeviceProfile.allAppsIconDrawablePaddingPx; CharSequence modifiedString = modifyTitleToSupportMultiLine( MeasureSpec.getSize(widthMeasureSpec) - getCompoundPaddingLeft() - getCompoundPaddingRight(), + allowedVerticalSpace, mLastOriginalText, - getPaint(), mBreakPointsIntArray); + getPaint(), + mBreakPointsIntArray, + getLineSpacingMultiplier(), + getLineSpacingExtra()); if (!TextUtils.equals(modifiedString, mLastModifiedText)) { mLastModifiedText = modifiedString; setText(modifiedString); @@ -785,7 +794,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, * many words as it can until the limit is reached. Once the limit is reached, we decide to * either return the original title or continue on a new line. How to get the new string is by * iterating through the list of break points and determining if the strings between the break - * points can fit within the line it is in. + * points can fit within the line it is in. We will show the modified string if there is enough + * horizontal and vertical space, otherwise this method will just return the original string. * Example assuming each character takes up one spot: * title = "Battery Stats", breakpoint = [6], stringPtr = 0, limitedWidth = 7 * We get the current word -> from sublist(0, breakpoint[i]+1) so sublist (0,7) -> Battery, @@ -794,8 +804,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, * if the first char is a SPACE, we trim to append "Stats". So resulting string would be * "Battery\nStats" */ - public static CharSequence modifyTitleToSupportMultiLine(int limitedWidth, CharSequence title, - TextPaint paint, IntArray breakPoints) { + public static CharSequence modifyTitleToSupportMultiLine(int limitedWidth, int limitedHeight, + CharSequence title, TextPaint paint, IntArray breakPoints, float spacingMultiplier, + float spacingExtra) { // current title is less than the width allowed so we can just skip if (title == null || paint.measureText(title, 0, title.length()) <= limitedWidth) { return title; @@ -816,11 +827,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, if (runningWidth <= limitedWidth) { newString.append(currentWord); } else { - // there is no more space - if (i == 0) { - // if the first words exceeds width, just return as the first line will ellipse - return title; - } else { + if (i != 0) { // If putting word onto a new line, make sure there is no space or new line // character in the beginning of the current word and just put in the rest of // the characters. @@ -834,8 +841,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, : EMPTY; } newString.append(NEW_LINE).append(lastCharacters); - return newString.toString(); + StaticLayout staticLayout = new StaticLayout(newString, paint, limitedWidth, + ALIGN_NORMAL, spacingMultiplier, spacingExtra, false); + if (staticLayout.getHeight() < limitedHeight) { + return newString.toString(); + } } + // if the first words exceeds width, just return as the first line will ellipse + return title; } if (i >= breakPoints.size()) { // no need to look forward into the string if we've already finished processing diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index c05afc94a7..bf35a0fc32 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -1133,6 +1133,10 @@ public class DeviceProfile { if (isVerticalBarLayout()) { hideWorkspaceLabelsIfNotEnoughSpace(); } + if (FeatureFlags.enableTwolineAllapps()) { + // Add extra textHeight to the existing allAppsCellHeight. + allAppsCellHeightPx += Utilities.calculateTextHeight(allAppsIconTextSizePx); + } updateHotseatSizes(iconSizePx); diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java index 769c787335..005e6dfe87 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java @@ -29,7 +29,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Flags; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.allapps.search.SearchAdapterProvider; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; @@ -138,7 +137,6 @@ public abstract class BaseAllAppsAdapter ex protected final OnClickListener mOnIconClickListener; protected final OnLongClickListener mOnIconLongClickListener; protected OnFocusChangeListener mIconFocusListener; - private final int mExtraTextHeight; public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater, AlphabeticalAppsList apps, SearchAdapterProvider adapterProvider) { @@ -150,8 +148,6 @@ public abstract class BaseAllAppsAdapter ex mOnIconLongClickListener = mActivityContext.getAllAppsItemLongClickListener(); mAdapterProvider = adapterProvider; - mExtraTextHeight = Utilities.calculateTextHeight( - mActivityContext.getDeviceProfile().allAppsIconTextSizePx); } /** Checks if the passed viewType represents all apps divider. */ @@ -177,9 +173,7 @@ public abstract class BaseAllAppsAdapter ex public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case VIEW_TYPE_ICON: - int layout = - !(Flags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) - ? R.layout.all_apps_icon + int layout = !FeatureFlags.enableTwolineAllapps() ? R.layout.all_apps_icon : R.layout.all_apps_icon_twoline; BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate( layout, parent, false); @@ -190,9 +184,6 @@ public abstract class BaseAllAppsAdapter ex // Ensure the all apps icon height matches the workspace icons in portrait mode. icon.getLayoutParams().height = mActivityContext.getDeviceProfile().allAppsCellHeightPx; - if (Flags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) { - icon.getLayoutParams().height += mExtraTextHeight; - } return new ViewHolder(icon); case VIEW_TYPE_EMPTY_SEARCH: return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search, diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 2da85e123f..ea763495a0 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -243,6 +243,9 @@ public final class FeatureFlags { // Aconfig migration complete for ENABLE_TWOLINE_ALLAPPS. public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(270390937, "ENABLE_TWOLINE_ALLAPPS", DISABLED, "Enables two line label inside all apps."); + public static boolean enableTwolineAllapps() { + return ENABLE_TWOLINE_ALLAPPS.get() || Flags.enableTwolineAllapps(); + } public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(270391693, "IME_STICKY_SNACKBAR_EDU", ENABLED, "Show sticky IME edu in AllApps"); diff --git a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java index bba8c89a05..914f363f41 100644 --- a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java +++ b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java @@ -20,7 +20,6 @@ import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.android.launcher3.BubbleTextView.DISPLAY_ALL_APPS; import static com.android.launcher3.BubbleTextView.DISPLAY_PREDICTION_ROW; -import static com.android.launcher3.config.FeatureFlags.ENABLE_TWOLINE_ALLAPPS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -36,7 +35,6 @@ import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.search.StringMatcherUtility; import com.android.launcher3.util.ActivityContextWrapper; import com.android.launcher3.util.IntArray; -import com.android.launcher3.util.TestUtil; import com.android.launcher3.util.rule.StaticMockitoRule; import com.android.launcher3.views.BaseDragLayer; @@ -75,6 +73,10 @@ public class BubbleTextViewTest { "LEGO®\nBuilder"; private static final String EMPTY_STRING = ""; private static final int CHAR_CNT = 7; + private static final int MAX_HEIGHT = Integer.MAX_VALUE; + private static final int LIMITED_HEIGHT = 357; /* allowedHeight in Pixel6 */ + private static final float SPACE_MULTIPLIER = 1; + private static final float SPACE_EXTRA = 0; private BubbleTextView mBubbleTextView; private ItemInfoWithIcon mItemInfoWithIcon; @@ -111,160 +113,150 @@ public class BubbleTextViewTest { @Test public void testEmptyString_flagOn() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - mItemInfoWithIcon.title = EMPTY_STRING; - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertNotEquals(TWO_LINE, mBubbleTextView.getMaxLines()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + mItemInfoWithIcon.title = EMPTY_STRING; + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertNotEquals(TWO_LINE, mBubbleTextView.getMaxLines()); } @Test public void testEmptyString_flagOff() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - mItemInfoWithIcon.title = EMPTY_STRING; - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(false); + mItemInfoWithIcon.title = EMPTY_STRING; + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testStringWithSpaceLongerThanCharLimit_flagOn() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "Battery Stats" - mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "Battery Stats" + mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void testStringWithSpaceLongerThanCharLimit_flagOff() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "Battery Stats" - mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(false); + // test string: "Battery Stats" + mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringNoSpaceLongerThanCharLimit_flagOn() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "flutterappflorafy" - mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "flutterappflorafy" + mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringNoSpaceLongerThanCharLimit_flagOff() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "flutterappflorafy" - mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(false); + // test string: "flutterappflorafy" + mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringWithSpaceLongerThanCharLimit_flagOn() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "System UWB Field Test" - mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "System UWB Field Test" + mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringWithSpaceLongerThanCharLimit_flagOff() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "System UWB Field Test" - mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(false); + // test string: "System UWB Field Test" + mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringSymbolLongerThanCharLimit_flagOn() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "LEGO®Builder" - mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringSymbolLongerThanCharLimit_flagOff() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "LEGO®Builder" - mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(false); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test @@ -273,8 +265,11 @@ public class BubbleTextViewTest { IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints( TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, MATCHER); CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth, + MAX_HEIGHT, TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(), - breakPoints); + breakPoints, + SPACE_MULTIPLIER, + SPACE_EXTRA); assertEquals(TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT_RESULT, newString); } @@ -283,9 +278,11 @@ public class BubbleTextViewTest { // test string: "flutterappflorafy" IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints( TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT, MATCHER); - CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth, + CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth, 0, TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(), - breakPoints); + breakPoints, + SPACE_MULTIPLIER, + SPACE_EXTRA); assertEquals(TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT, newString); } @@ -295,8 +292,11 @@ public class BubbleTextViewTest { IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints( TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, MATCHER); CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth, + MAX_HEIGHT, TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(), - breakPoints); + breakPoints, + SPACE_MULTIPLIER, + SPACE_EXTRA); assertEquals(TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT_RESULT, newString); } @@ -305,25 +305,57 @@ public class BubbleTextViewTest { // test string: "LEGO®Builder" IntArray breakPoints = StringMatcherUtility.getListOfBreakpoints( TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT, MATCHER); - CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine(mLimitedWidth, + CharSequence newString = BubbleTextView.modifyTitleToSupportMultiLine( + mLimitedWidth, + MAX_HEIGHT, TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT, mBubbleTextView.getPaint(), - breakPoints); + breakPoints, + SPACE_MULTIPLIER, + SPACE_EXTRA); assertEquals(TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT_RESULT, newString); } @Test - public void testEnsurePredictionRowIsOneLine() { - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "Battery Stats" - mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.setDisplay(DISPLAY_PREDICTION_ROW); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, 0); - mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + public void testEnsurePredictionRowIsTwoLine() { + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "Battery Stats" + mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.setDisplay(DISPLAY_PREDICTION_ROW); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); + } + + @Test + public void modifyTitleToSupportMultiLine_whenLimitedHeight_shouldBeOneLine() { + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); + } + + @Test + public void modifyTitleToSupportMultiLine_whenUnlimitedHeight_shouldBeTwoLine() { + Mockito.when(Flags.enableTwolineAllapps()).thenReturn(true); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + + mBubbleTextView.onPreDraw(); + + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } }