Support two line text in AllApps/OnDeviceSearch w/ feature flag

Made separate feature flag for on device search
Add unit test to test twoLine string
- Unit tests for testing newStringThatShouldSupportTwoLineText() in BubbleTextView.java. This class tests a couple of strings
and uses the getLineCount() to determine if the test passes. Verifying with getLineCount() is sufficient since BubbleTextView can only be in one line or two lines,
and this is enough to ensure whether the string should be specifically wrapped onto the second line and to ensure truncation.

bug: 201388851
test: presubmit, ran locally on big and small device, before: https://screenshot.googleplex.com/3Q6pwveFDZqxDXL (ORIGINAL TWO LINE TEXT)
after:  https://screenshot.googleplex.com/7pkwUto6HGzMYoT

Change-Id: I93e6ed179e1081d5cdffc6db9c7ae34de8021c24
This commit is contained in:
Brandon Dayauon
2023-01-06 12:38:55 -08:00
parent c523de6dc2
commit cf88ea1e62
7 changed files with 533 additions and 8 deletions
@@ -16,13 +16,20 @@
package com.android.launcher3.search;
import android.text.TextUtils;
import com.android.launcher3.util.IntArray;
import java.text.Collator;
import java.util.stream.IntStream;
/**
* Utilities for matching query string to target string.
*/
public class StringMatcherUtility {
private static final Character SPACE = ' ';
/**
* Returns {@code true} if {@code query} is a prefix of a substring in {@code target}. How to
* break target to valid substring is defined in the given {@code matcher}.
@@ -58,6 +65,41 @@ public class StringMatcherUtility {
return false;
}
/**
* Returns a list of breakpoints wherever the string contains a break. For example:
* "t-mobile" would have breakpoints at [0, 1]
* "Agar.io" would have breakpoints at [3, 4]
* "LEGO®Builder" would have a breakpoint at [4]
*/
public static IntArray getListOfBreakpoints(CharSequence input, StringMatcher matcher) {
int inputLength = input.length();
if ((inputLength <= 2) || TextUtils.indexOf(input, SPACE) != -1) {
// when there is a space in the string, return a list where the elements are the
// position of the spaces - 1. This is to make the logic consistent where breakpoints
// are placed
return IntArray.wrap(IntStream.range(0, inputLength)
.filter(i -> input.charAt(i) == SPACE)
.map(i -> i - 1)
.toArray());
}
IntArray listOfBreakPoints = new IntArray();
int prevType;
int thisType = Character.getType(Character.codePointAt(input, 0));
int nextType = Character.getType(Character.codePointAt(input, 1));
for (int i = 1; i < inputLength; i++) {
prevType = thisType;
thisType = nextType;
nextType = i < (inputLength - 1)
? Character.getType(Character.codePointAt(input, i + 1))
: Character.UNASSIGNED;
if (matcher.isBreak(thisType, prevType, nextType)) {
// breakpoint is at previous
listOfBreakPoints.add(i-1);
}
}
return listOfBreakPoints;
}
/**
* Performs locale sensitive string comparison using {@link Collator}.
*/
@@ -118,7 +160,11 @@ public class StringMatcherUtility {
}
switch (thisType) {
case Character.UPPERCASE_LETTER:
if (nextType == Character.UPPERCASE_LETTER) {
// takes care of the case where there are consistent uppercase letters as well
// as a special symbol following the capitalize letters for example: LEGO®
if (nextType != Character.UPPERCASE_LETTER && nextType != Character.OTHER_SYMBOL
&& nextType != Character.DECIMAL_DIGIT_NUMBER
&& nextType != Character.UNASSIGNED) {
return true;
}
// Follow through