From 82b016cb56540fe26213e817dd0dd668099c8e20 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 8 May 2015 17:00:10 -0700 Subject: Trim all whitespace from titles and labels. Bug: 20953160 Change-Id: I1610df5e445a4139522226f68fa6439926bc70c6 --- .../android/launcher3/AlphabeticalAppsList.java | 5 ++-- src/com/android/launcher3/AppInfo.java | 4 +-- src/com/android/launcher3/AppsContainerView.java | 18 +++++++----- src/com/android/launcher3/Folder.java | 5 ++-- src/com/android/launcher3/FolderIcon.java | 2 +- src/com/android/launcher3/FolderInfo.java | 2 +- src/com/android/launcher3/IconCache.java | 10 +++---- .../android/launcher3/InstallShortcutReceiver.java | 2 +- .../launcher3/LauncherAppWidgetProviderInfo.java | 2 +- src/com/android/launcher3/LauncherModel.java | 33 ++++++++++------------ src/com/android/launcher3/ShortcutInfo.java | 8 +++--- src/com/android/launcher3/Utilities.java | 15 ++++++++++ .../WorkspaceAccessibilityHelper.java | 2 +- .../launcher3/compat/AlphabeticIndexCompat.java | 8 ++++-- .../compat/AppWidgetManagerCompatV16.java | 2 +- .../android/launcher3/widget/PackageItemInfo.java | 2 +- src/com/android/launcher3/widget/WidgetCell.java | 7 ++--- 17 files changed, 72 insertions(+), 55 deletions(-) (limited to 'src/com/android/launcher3') diff --git a/src/com/android/launcher3/AlphabeticalAppsList.java b/src/com/android/launcher3/AlphabeticalAppsList.java index 70e36a744..f075e417d 100644 --- a/src/com/android/launcher3/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/AlphabeticalAppsList.java @@ -29,8 +29,7 @@ class AppNameComparator { mAppNameComparator = new Comparator() { public final int compare(AppInfo a, AppInfo b) { // Order by the title - int result = collator.compare(a.title.toString().trim(), - b.title.toString().trim()); + int result = collator.compare(a.title.toString(), b.title.toString()); if (result == 0) { // If two apps have the same title, then order by the component name result = a.componentName.compareTo(b.componentName); @@ -349,7 +348,7 @@ public class AlphabeticalAppsList { int appIndex = 0; int numApps = mApps.size(); for (AppInfo info : mApps) { - String sectionName = mIndexer.computeSectionName(info.title.toString().trim()); + String sectionName = mIndexer.computeSectionName(info.title); // Check if we want to retain this app if (mFilter != null && !mFilter.retainApp(info, sectionName)) { diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java index 7c6b0664c..58a57a1fe 100644 --- a/src/com/android/launcher3/AppInfo.java +++ b/src/com/android/launcher3/AppInfo.java @@ -105,7 +105,7 @@ public class AppInfo extends ItemInfo { public AppInfo(AppInfo info) { super(info); componentName = info.componentName; - title = info.title.toString(); + title = Utilities.trim(info.title); intent = new Intent(info.intent); flags = info.flags; firstInstallTime = info.firstInstallTime; @@ -114,7 +114,7 @@ public class AppInfo extends ItemInfo { @Override public String toString() { - return "ApplicationInfo(title=" + title.toString() + " id=" + this.id + return "ApplicationInfo(title=" + title + " id=" + this.id + " type=" + this.itemType + " container=" + this.container + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos) diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java index 993f9c857..aa6c05993 100644 --- a/src/com/android/launcher3/AppsContainerView.java +++ b/src/com/android/launcher3/AppsContainerView.java @@ -36,6 +36,7 @@ import android.widget.TextView; import com.android.launcher3.util.Thunk; import java.util.List; +import java.util.regex.Pattern; /** @@ -56,6 +57,8 @@ public class AppsContainerView extends BaseContainerView implements DragSource, private static final int FADE_OUT_DURATION = 100; private static final int SEARCH_TRANSLATION_X_DP = 18; + private static final Pattern SPLIT_PATTERN = Pattern.compile("[\\s|\\p{javaSpaceChar}]+"); + @Thunk Launcher mLauncher; @Thunk AlphabeticalAppsList mApps; private AppsGridAdapter mAdapter; @@ -430,23 +433,24 @@ public class AppsContainerView extends BaseContainerView implements DragSource, @Override public void afterTextChanged(final Editable s) { - if (s.toString().isEmpty()) { + String queryText = s.toString(); + if (queryText.isEmpty()) { mApps.setFilter(null); } else { String formatStr = getResources().getString(R.string.apps_view_no_search_results); - mAdapter.setEmptySearchText(String.format(formatStr, s.toString())); + mAdapter.setEmptySearchText(String.format(formatStr, queryText)); - final String filterText = s.toString().toLowerCase().replaceAll("\\s+", ""); + final String queryTextLower = queryText.toLowerCase(); mApps.setFilter(new AlphabeticalAppsList.Filter() { @Override public boolean retainApp(AppInfo info, String sectionName) { - String title = info.title.toString(); - if (sectionName.toLowerCase().contains(filterText)) { + if (sectionName.toLowerCase().contains(queryTextLower)) { return true; } - String[] words = title.toLowerCase().split("\\s+"); + String title = info.title.toString(); + String[] words = SPLIT_PATTERN.split(title.toLowerCase()); for (int i = 0; i < words.length; i++) { - if (words[i].startsWith(filterText)) { + if (words[i].startsWith(queryTextLower)) { return true; } } diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index a2828054c..7a3ae3995 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -296,13 +296,14 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mFolderName.setHint(sHintText); // Convert to a string here to ensure that no other state associated with the text field // gets saved. - String newTitle = mFolderName.getText().toString(); + CharSequence newTitle = mFolderName.getText(); mInfo.setTitle(newTitle); LauncherModel.updateItemInDatabase(mLauncher, mInfo); if (commit) { sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, - String.format(getContext().getString(R.string.folder_renamed), newTitle)); + String.format(getContext().getString(R.string.folder_renamed), + newTitle.toString())); } // In order to clear the focus from the text field, we set the focus on ourself. This // ensures that every time the field is clicked, focus is gained, giving reliable behavior. diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java index f5836c295..b161b1cd3 100644 --- a/src/com/android/launcher3/FolderIcon.java +++ b/src/com/android/launcher3/FolderIcon.java @@ -710,7 +710,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { } public void onTitleChanged(CharSequence title) { - mFolderName.setText(title.toString()); + mFolderName.setText(title); setContentDescription(String.format(getContext().getString(R.string.folder_name_format), title)); } diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java index 80b156413..9675371d5 100644 --- a/src/com/android/launcher3/FolderInfo.java +++ b/src/com/android/launcher3/FolderInfo.java @@ -87,7 +87,7 @@ public class FolderInfo extends ItemInfo { } public void setTitle(CharSequence title) { - this.title = title; + this.title = Utilities.trim(title); for (int i = 0; i < listeners.size(); i++) { listeners.get(i).onTitleChanged(title); } diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index 6c2aa397d..0596fbe16 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -400,7 +400,7 @@ public class IconCache { UserHandleCompat user = info == null ? application.user : info.getUser(); CacheEntry entry = cacheLocked(application.componentName, info, user, false, useLowResIcon); - application.title = entry.title; + application.title = Utilities.trim(entry.title); application.iconBitmap = getNonNullIcon(entry, user); application.contentDescription = entry.contentDescription; application.usingLowResIcon = entry.isLowResIcon; @@ -413,7 +413,7 @@ public class IconCache { CacheEntry entry = cacheLocked(application.componentName, null, application.user, false, application.usingLowResIcon); if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) { - application.title = entry.title; + application.title = Utilities.trim(entry.title); application.iconBitmap = entry.icon; application.contentDescription = entry.contentDescription; application.usingLowResIcon = entry.isLowResIcon; @@ -464,7 +464,7 @@ public class IconCache { UserHandleCompat user, boolean usePkgIcon, boolean useLowResIcon) { CacheEntry entry = cacheLocked(component, info, user, usePkgIcon, useLowResIcon); shortcutInfo.setIcon(getNonNullIcon(entry, user)); - shortcutInfo.title = entry.title; + shortcutInfo.title = Utilities.trim(entry.title); shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user); shortcutInfo.usingLowResIcon = entry.isLowResIcon; } @@ -477,7 +477,7 @@ public class IconCache { PackageItemInfo infoOut) { CacheEntry entry = getEntryForPackageLocked(packageName, user, useLowResIcon); infoOut.iconBitmap = getNonNullIcon(entry, user); - infoOut.title = entry.title; + infoOut.title = Utilities.trim(entry.title); infoOut.usingLowResIcon = entry.isLowResIcon; infoOut.contentDescription = entry.contentDescription; } @@ -530,7 +530,7 @@ public class IconCache { } if (TextUtils.isEmpty(entry.title) && info != null) { - entry.title = info.getLabel().toString(); + entry.title = info.getLabel(); entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user); } } diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 23bcc8577..115598f7b 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -247,7 +247,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { try { PackageManager pm = context.getPackageManager(); ActivityInfo info = pm.getActivityInfo(intent.getComponent(), 0); - name = info.loadLabel(pm).toString(); + name = info.loadLabel(pm); } catch (PackageManager.NameNotFoundException nnfe) { return ""; } diff --git a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java index bb4580ce7..af680f247 100644 --- a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java +++ b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java @@ -66,7 +66,7 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo { public String getLabel(PackageManager packageManager) { if (isCustomWidget) { - return label.toString().trim(); + return Utilities.trim(label); } return super.loadLabel(packageManager); } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index e81c8c285..3987c0207 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -969,7 +969,7 @@ public class LauncherModel extends BroadcastReceiver break; } - folderInfo.title = c.getString(titleIndex); + folderInfo.title = Utilities.trim(c.getString(titleIndex)); folderInfo.id = id; folderInfo.container = c.getInt(containerIndex); folderInfo.screenId = c.getInt(screenIndex); @@ -2144,7 +2144,7 @@ public class LauncherModel extends BroadcastReceiver id = c.getLong(idIndex); FolderInfo folderInfo = findOrMakeFolder(sBgFolders, id); - folderInfo.title = c.getString(titleIndex); + folderInfo.title = Utilities.trim(c.getString(titleIndex)); folderInfo.id = id; container = c.getInt(containerIndex); folderInfo.container = container; @@ -3199,7 +3199,7 @@ public class LauncherModel extends BroadcastReceiver if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction()) && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { si.updateIcon(mIconCache); - si.title = appInfo.title.toString(); + si.title = Utilities.trim(appInfo.title); si.contentDescription = appInfo.contentDescription; infoUpdated = true; } @@ -3428,18 +3428,17 @@ public class LauncherModel extends BroadcastReceiver if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) { String title = (cursor != null) ? cursor.getString(titleIndex) : null; if (!TextUtils.isEmpty(title)) { - info.title = title; + info.title = Utilities.trim(title); } } else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { if (TextUtils.isEmpty(info.title)) { - info.title = (cursor != null) ? cursor.getString(titleIndex) : ""; + info.title = (cursor != null) ? Utilities.trim(cursor.getString(titleIndex)) : ""; } } else { throw new InvalidParameterException("Invalid restoreType " + promiseType); } - info.contentDescription = mUserManager.getBadgedLabelForUser( - info.title.toString(), info.user); + info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; info.promisedIntent = intent; info.status = promiseType; @@ -3501,7 +3500,7 @@ public class LauncherModel extends BroadcastReceiver // from the db if (TextUtils.isEmpty(info.title) && c != null) { - info.title = c.getString(titleIndex); + info.title = Utilities.trim(c.getString(titleIndex)); } // fall back to the class name of the activity @@ -3511,8 +3510,7 @@ public class LauncherModel extends BroadcastReceiver info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; info.user = user; - info.contentDescription = mUserManager.getBadgedLabelForUser( - info.title.toString(), info.user); + info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); if (lai != null) { info.flags = AppInfo.initFlags(lai); } @@ -3578,7 +3576,7 @@ public class LauncherModel extends BroadcastReceiver // TODO: If there's an explicit component and we can't install that, delete it. - info.title = c.getString(titleIndex); + info.title = Utilities.trim(c.getString(titleIndex)); int iconType = c.getInt(iconTypeIndex); switch (iconType) { @@ -3656,9 +3654,8 @@ public class LauncherModel extends BroadcastReceiver } info.setIcon(icon); - info.title = name; - info.contentDescription = mUserManager.getBadgedLabelForUser( - info.title.toString(), info.user); + info.title = Utilities.trim(name); + info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); info.intent = intent; info.customIcon = customIcon; info.iconResource = iconResource; @@ -3699,16 +3696,16 @@ public class LauncherModel extends BroadcastReceiver labelA = mLabelCache.get(a); } else { labelA = (a instanceof LauncherAppWidgetProviderInfo) - ? mManager.loadLabel((LauncherAppWidgetProviderInfo) a) - : ((ResolveInfo) a).loadLabel(mPackageManager).toString().trim(); + ? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) a)) + : Utilities.trim(((ResolveInfo) a).loadLabel(mPackageManager)); mLabelCache.put(a, labelA); } if (mLabelCache.containsKey(b)) { labelB = mLabelCache.get(b); } else { labelB = (b instanceof LauncherAppWidgetProviderInfo) - ? mManager.loadLabel((LauncherAppWidgetProviderInfo) b) - : ((ResolveInfo) b).loadLabel(mPackageManager).toString().trim(); + ? Utilities.trim(mManager.loadLabel((LauncherAppWidgetProviderInfo) b)) + : Utilities.trim(((ResolveInfo) b).loadLabel(mPackageManager)); mLabelCache.put(b, labelB); } return mCollator.compare(labelA, labelB); diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java index 6354fcd28..8be48721c 100644 --- a/src/com/android/launcher3/ShortcutInfo.java +++ b/src/com/android/launcher3/ShortcutInfo.java @@ -153,7 +153,7 @@ public class ShortcutInfo extends ItemInfo { Bitmap icon, UserHandleCompat user) { this(); this.intent = intent; - this.title = title; + this.title = Utilities.trim(title); this.contentDescription = contentDescription; mIcon = icon; this.user = user; @@ -161,7 +161,7 @@ public class ShortcutInfo extends ItemInfo { public ShortcutInfo(Context context, ShortcutInfo info) { super(info); - title = info.title.toString(); + title = Utilities.trim(info.title); intent = new Intent(info.intent); if (info.iconResource != null) { iconResource = new Intent.ShortcutIconResource(); @@ -179,7 +179,7 @@ public class ShortcutInfo extends ItemInfo { /** TODO: Remove this. It's only called by ApplicationInfo.makeShortcut. */ public ShortcutInfo(AppInfo info) { super(info); - title = info.title.toString(); + title = Utilities.trim(info.title); intent = new Intent(info.intent); customIcon = false; flags = info.flags; @@ -281,7 +281,7 @@ public class ShortcutInfo extends ItemInfo { public static ShortcutInfo fromActivityInfo(LauncherActivityInfoCompat info, Context context) { final ShortcutInfo shortcut = new ShortcutInfo(); shortcut.user = info.getUser(); - shortcut.title = info.getLabel().toString(); + shortcut.title = Utilities.trim(info.getLabel()); shortcut.contentDescription = UserManagerCompat.getInstance(context) .getBadgedLabelForUser(info.getLabel(), info.getUser()); shortcut.customIcon = false; diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 2dbf078a4..298174768 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -54,6 +54,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Comparator; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Various utilities shared amongst the Launcher's classes. @@ -67,6 +69,9 @@ public final class Utilities { private static final Rect sOldBounds = new Rect(); private static final Canvas sCanvas = new Canvas(); + private static final Pattern sTrimPattern = + Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$"); + static { sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG)); @@ -616,4 +621,14 @@ public final class Utilities { return false; } + + /** + * Trims the string, removing all whitespace at the beginning and end of the string. + * Non-breaking whitespaces are also removed. + */ + public static String trim(CharSequence s) { + // Just strip any sequence of whitespace or java space characters from the beginning and end + Matcher m = sTrimPattern.matcher(s); + return m.replaceAll("$1"); + } } diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java index 42e9e3c58..6f89d0eb0 100644 --- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java +++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java @@ -145,7 +145,7 @@ public class WorkspaceAccessibilityHelper extends DragAndDropAccessibilityDelega if (info instanceof ShortcutInfo) { return mContext.getString(R.string.create_folder_with, info.title); } else if (info instanceof FolderInfo) { - if (TextUtils.isEmpty(info.title.toString().trim())) { + if (TextUtils.isEmpty(info.title)) { // Find the first item in the folder. FolderInfo folder = (FolderInfo) info; ShortcutInfo firstItem = null; diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java index f890706ff..18cdc81f3 100644 --- a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java +++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java @@ -1,6 +1,7 @@ package com.android.launcher3.compat; import android.content.Context; +import com.android.launcher3.Utilities; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -102,10 +103,11 @@ public class AlphabeticIndexCompat extends BaseAlphabeticIndex { /** * Computes the section name for an given string {@param s}. */ - public String computeSectionName(String s) { + public String computeSectionName(CharSequence cs) { + String s = Utilities.trim(cs); String sectionName = getBucketLabel(getBucketIndex(s)); - if (sectionName.trim().isEmpty() && s.length() > 0) { - boolean startsWithDigit = Character.isDigit(Character.codePointAt(s.trim(), 0)); + if (Utilities.trim(sectionName).isEmpty() && s.length() > 0) { + boolean startsWithDigit = Character.isDigit(s.codePointAt(0)); if (startsWithDigit) { // Digit section return "#"; diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java index 767f16f62..967b53b0b 100644 --- a/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java +++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatV16.java @@ -46,7 +46,7 @@ class AppWidgetManagerCompatV16 extends AppWidgetManagerCompat { @Override public String loadLabel(LauncherAppWidgetProviderInfo info) { - return info.label.trim(); + return Utilities.trim(info.label); } @Override diff --git a/src/com/android/launcher3/widget/PackageItemInfo.java b/src/com/android/launcher3/widget/PackageItemInfo.java index 1a1de55c2..8f45a7754 100644 --- a/src/com/android/launcher3/widget/PackageItemInfo.java +++ b/src/com/android/launcher3/widget/PackageItemInfo.java @@ -49,7 +49,7 @@ public class PackageItemInfo extends ItemInfo { @Override public String toString() { - return "PackageItemInfo(title=" + title.toString() + " id=" + this.id + return "PackageItemInfo(title=" + title + " id=" + this.id + " type=" + this.itemType + " container=" + this.container + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos) diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index 2df170eff..27b7e6df5 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -222,10 +222,9 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { * Helper method to get the string info of the tag. */ private String getTagToString() { - if (getTag() instanceof PendingAddWidgetInfo) { - return ((PendingAddWidgetInfo)getTag()).toString(); - } else if (getTag() instanceof PendingAddShortcutInfo) { - return ((PendingAddShortcutInfo)getTag()).toString(); + if (getTag() instanceof PendingAddWidgetInfo || + getTag() instanceof PendingAddShortcutInfo) { + return getTag().toString(); } return ""; } -- cgit v1.2.3