Merge "Refactor FolderNameInfos." into ub-launcher3-rvc-dev
diff --git a/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java b/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
index d927ffc..b7ba106 100644
--- a/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.folder;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -61,16 +62,16 @@
         ArrayList<WorkspaceItemInfo> list = new ArrayList<>();
         list.add(mItem1);
         list.add(mItem2);
-        FolderNameInfo[] nameInfos =
-                new FolderNameInfo[FolderNameProvider.SUGGEST_MAX];
+        FolderNameInfos nameInfos = new FolderNameInfos();
         new FolderNameProvider().getSuggestedFolderName(mContext, list, nameInfos);
-        assertEquals("Work", nameInfos[0].getLabel());
+        assertEquals("Work", nameInfos.getLabels()[0]);
 
-        nameInfos[0] = new FolderNameInfo("candidate1", 0.9);
-        nameInfos[1] = new FolderNameInfo("candidate2", 0.8);
-        nameInfos[2] = new FolderNameInfo("candidate3", 0.7);
+        nameInfos.setLabel(0, "candidate1", 1.0f);
+        nameInfos.setLabel(1, "candidate2", 1.0f);
+        nameInfos.setLabel(2, "candidate3", 1.0f);
         new FolderNameProvider().getSuggestedFolderName(mContext, list, nameInfos);
-        assertEquals("Work", nameInfos[3].getLabel());
-
+        assertEquals("Work", nameInfos.getLabels()[3]);
+        assertTrue(nameInfos.hasSuggestions());
+        assertTrue(nameInfos.hasPrimary());
     }
 }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index e950f3c..4af3544 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -28,16 +28,12 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
 import static com.android.launcher3.model.data.FolderInfo.FLAG_MANUAL_FOLDER_NAME;
 
-import static java.util.Arrays.asList;
-import static java.util.Optional.ofNullable;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.annotation.SuppressLint;
 import android.appwidget.AppWidgetHostView;
 import android.content.Context;
-import android.content.Intent;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -104,6 +100,7 @@
 import java.util.Objects;
 import java.util.StringJoiner;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Represents a set of icons chosen by the user or generated by the system.
@@ -327,11 +324,7 @@
     public void startEditingFolderName() {
         post(() -> {
             if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
-                ofNullable(mInfo)
-                        .map(info -> info.suggestedFolderNames)
-                        .map(folderNames -> (FolderNameInfo[]) folderNames
-                                .getParcelableArrayExtra(FolderInfo.EXTRA_FOLDER_SUGGESTIONS))
-                        .ifPresent(this::showLabelSuggestions);
+                showLabelSuggestions();
             }
             mFolderName.setHint("");
             mIsEditingName = true;
@@ -461,32 +454,24 @@
      * Show suggested folder title in FolderEditText if the first suggestion is non-empty, push
      * rest of the suggestions to InputMethodManager.
      */
-    private void showLabelSuggestions(FolderNameInfo[] nameInfos) {
-        if (nameInfos == null) {
+    private void showLabelSuggestions() {
+        if (mInfo.suggestedFolderNames == null) {
             return;
         }
-        // Open the Folder and Keyboard when the first or second suggestion is valid non-empty
-        // string.
-        boolean shouldOpen = nameInfos.length > 0 && nameInfos[0] != null && !isEmpty(
-                nameInfos[0].getLabel())
-                || nameInfos.length > 1 && nameInfos[1] != null && !isEmpty(
-                nameInfos[1].getLabel());
-
-        if (shouldOpen) {
+        if (mInfo.suggestedFolderNames.hasSuggestions()) {
             // update the primary suggestion if the folder name is empty.
             if (isEmpty(mFolderName.getText())) {
-                CharSequence firstLabel = nameInfos[0] == null ? "" : nameInfos[0].getLabel();
-                if (!isEmpty(firstLabel)) {
+                if (mInfo.suggestedFolderNames.hasPrimary()) {
                     mFolderName.setHint("");
-                    mFolderName.setText(firstLabel);
+                    mFolderName.setText(mInfo.suggestedFolderNames.getLabels()[0]);
                     mFolderName.selectAll();
                 }
             }
             mFolderName.showKeyboard();
             mFolderName.displayCompletions(
-                    asList(nameInfos).subList(0, nameInfos.length).stream()
+                    Stream.of(mInfo.suggestedFolderNames.getLabels())
                             .filter(Objects::nonNull)
-                            .map(s -> s.getLabel().toString())
+                            .map(Object::toString)
                             .filter(s -> !s.isEmpty())
                             .filter(s -> !s.equalsIgnoreCase(mFolderName.getText().toString()))
                             .collect(Collectors.toList()));
@@ -1021,14 +1006,11 @@
         if (FeatureFlags.FOLDER_NAME_SUGGEST.get() && !isBind
                 && total > 1 /* no need to update if there's one icon */) {
             Executors.MODEL_EXECUTOR.post(() -> {
-                FolderNameInfo[] nameInfos =
-                        new FolderNameInfo[FolderNameProvider.SUGGEST_MAX];
+                FolderNameInfos nameInfos = new FolderNameInfos();
                 FolderNameProvider fnp = FolderNameProvider.newInstance(getContext());
                 fnp.getSuggestedFolderName(
                         getContext(), mInfo.contents, nameInfos);
-                mInfo.suggestedFolderNames = new Intent().putExtra(
-                        FolderInfo.EXTRA_FOLDER_SUGGESTIONS,
-                        nameInfos);
+                mInfo.suggestedFolderNames = nameInfos;
             });
         }
     }
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index e24033f..152fd37 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -84,7 +84,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
-import java.util.stream.Stream;
+
 
 /**
  * An icon that can appear on in the workspace representing an {@link Folder}.
@@ -411,8 +411,7 @@
             if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true);
             final int finalIndex = index;
 
-            FolderNameInfo[] nameInfos =
-                    new FolderNameInfo[FolderNameProvider.SUGGEST_MAX];
+            FolderNameInfos nameInfos = new FolderNameInfos();
             if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
                 Executors.MODEL_EXECUTOR.post(() -> {
                     d.folderNameProvider.getSuggestedFolderName(
@@ -428,7 +427,7 @@
     }
 
     private void showFinalView(int finalIndex, final WorkspaceItemInfo item,
-            FolderNameInfo[] nameInfos, InstanceId instanceId) {
+            FolderNameInfos nameInfos, InstanceId instanceId) {
         postDelayed(() -> {
             mPreviewItemManager.hidePreviewItem(finalIndex, false);
             mFolder.showItem(item);
@@ -440,7 +439,7 @@
     /**
      * Set the suggested folder name.
      */
-    public void setLabelSuggestion(FolderNameInfo[] nameInfos, InstanceId instanceId) {
+    public void setLabelSuggestion(FolderNameInfos nameInfos, InstanceId instanceId) {
         if (!FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
             return;
         }
@@ -448,22 +447,21 @@
                 || mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) {
             return;
         }
-        if (nameInfos == null || Stream.of(nameInfos)
-                .allMatch(nameInfo -> nameInfo == null || isEmpty(nameInfo.getLabel()))) {
+        if (nameInfos == null || !nameInfos.hasSuggestions()) {
             StatsLogManager.newInstance(getContext()).logger()
                     .withInstanceId(instanceId)
                     .withItemInfo(mInfo)
                     .log(LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS);
             return;
         }
-        if (nameInfos[0] == null || isEmpty(nameInfos[0].getLabel())) {
+        if (!nameInfos.hasPrimary()) {
             StatsLogManager.newInstance(getContext()).logger()
                     .withInstanceId(instanceId)
                     .withItemInfo(mInfo)
                     .log(LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY);
             return;
         }
-        CharSequence newTitle = nameInfos[0].getLabel();
+        CharSequence newTitle = nameInfos.getLabels()[0];
         FromState fromState = mInfo.getFromLabelState();
 
         mInfo.setTitle(newTitle);
diff --git a/src/com/android/launcher3/folder/FolderNameInfo.java b/src/com/android/launcher3/folder/FolderNameInfo.java
deleted file mode 100644
index 1841cd9..0000000
--- a/src/com/android/launcher3/folder/FolderNameInfo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.folder;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import androidx.annotation.NonNull;
-
-/**
- * Information about a single label suggestions of the Folder.
- */
-
-public final class FolderNameInfo implements Parcelable {
-    private final double mScore;
-    private final CharSequence mLabel;
-
-    /**
-     * Create a simple completion with label.
-     *
-     * @param label The text that should be inserted into the editor and pushed to
-     *              InputMethodManager suggestions.
-     * @param score The score for the label between 0.0 and 1.0.
-     */
-    public FolderNameInfo(CharSequence label, double score) {
-        mScore = score;
-        mLabel = label;
-    }
-
-    private FolderNameInfo(Parcel source) {
-        mScore = source.readDouble();
-        mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-    }
-
-    public CharSequence getLabel() {
-        return mLabel;
-    }
-
-    public double getScore() {
-        return mScore;
-    }
-
-    /**
-     * Used to package this object into a {@link Parcel}.
-     *
-     * @param dest  The {@link Parcel} to be written.
-     * @param flags The flags used for parceling.
-     */
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeDouble(mScore);
-        TextUtils.writeToParcel(mLabel, dest, flags);
-    }
-
-    /**
-     * Used to make this class parcelable.
-     */
-    @NonNull
-    public static final Parcelable.Creator<FolderNameInfo> CREATOR =
-            new Parcelable.Creator<FolderNameInfo>() {
-                public FolderNameInfo createFromParcel(Parcel source) {
-                    return new FolderNameInfo(source);
-                }
-
-                public FolderNameInfo[] newArray(int size) {
-                    return new FolderNameInfo[size];
-                }
-            };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        return String.format("%s:%.2f", mLabel, mScore);
-    }
-}
diff --git a/src/com/android/launcher3/folder/FolderNameInfos.java b/src/com/android/launcher3/folder/FolderNameInfos.java
new file mode 100644
index 0000000..457ae87
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderNameInfos.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.folder;
+
+import android.text.TextUtils;
+
+import androidx.annotation.NonNull;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Information about a  label suggestions of a Folder.
+ */
+
+public class FolderNameInfos {
+    public static final int SUCCESS = 1;
+    public static final int HAS_PRIMARY = 1 << 1;
+    public static final int HAS_SUGGESTIONS = 1 << 2;
+    public static final int ERROR_NO_PROVIDER = 1 << 3;
+    public static final int ERROR_APP_LOOKUP_FAILED = 1 << 4;
+    public static final int ERROR_ALL_APP_LOOKUP_FAILED = 1 << 5;
+    public static final int ERROR_NO_LABELS_GENERATED = 1 << 6;
+    public static final int ERROR_LABEL_LOOKUP_FAILED = 1 << 7;
+    public static final int ERROR_ALL_LABEL_LOOKUP_FAILED = 1 << 8;
+    public static final int ERROR_NO_PACKAGES = 1 << 9;
+
+    private int mStatus;
+    private final CharSequence[] mLabels;
+    private final Float[] mScores;
+
+    public FolderNameInfos() {
+        mStatus = 0;
+        mLabels = new CharSequence[FolderNameProvider.SUGGEST_MAX];
+        mScores = new Float[FolderNameProvider.SUGGEST_MAX];
+    }
+
+    /**
+     * set the status of FolderNameInfos.
+     */
+    public void setStatus(int statusBit) {
+        mStatus = mStatus | statusBit;
+    }
+
+    /**
+     * returns status of FolderNameInfos generations.
+     */
+    public int status() {
+        return mStatus;
+    }
+
+    /**
+     * return true if the first suggestion is a Primary suggestion.
+     */
+    public boolean hasPrimary() {
+        return (mStatus & HAS_PRIMARY) > 0 && (mLabels[0] != null);
+    }
+
+    /**
+     * return true if there is at least one valid suggestion.
+     */
+    public boolean hasSuggestions() {
+        for (CharSequence l : mLabels) {
+            if (l != null && !TextUtils.isEmpty(l)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * assign label and score in the specified index.
+     */
+    public void setLabel(int index, CharSequence label, Float score) {
+        if (index < mLabels.length) {
+            mLabels[index] = label;
+            mScores[index] = score;
+        }
+    }
+
+    /**
+     * returns true if the label is found in label suggestions/
+     */
+    public boolean contains(CharSequence label) {
+        return Arrays.stream(mLabels)
+                .filter(Objects::nonNull)
+                .anyMatch(l -> l.toString().equalsIgnoreCase(label.toString()));
+    }
+
+
+    public CharSequence[] getLabels() {
+        return mLabels;
+    }
+
+    public Float[] getScores() {
+        return mScores;
+    }
+
+    @Override
+    @NonNull
+    public String toString() {
+        return String.format("status=%s, labels=%s", Integer.toBinaryString(mStatus),
+                Arrays.toString(mLabels));
+    }
+}
+
diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java
index 2be0bce..d166e27 100644
--- a/src/com/android/launcher3/folder/FolderNameProvider.java
+++ b/src/com/android/launcher3/folder/FolderNameProvider.java
@@ -96,10 +96,10 @@
      */
     public void getSuggestedFolderName(Context context,
             ArrayList<WorkspaceItemInfo> workspaceItemInfos,
-            FolderNameInfo[] nameInfos) {
+            FolderNameInfos nameInfos) {
         Preconditions.assertWorkerThread();
         if (DEBUG) {
-            Log.d(TAG, "getSuggestedFolderName:" + Arrays.toString(nameInfos));
+            Log.d(TAG, "getSuggestedFolderName:" + nameInfos.toString());
         }
         // If all the icons are from work profile,
         // Then, suggest "Work" as the folder name
@@ -124,7 +124,7 @@
             info.ifPresent(i -> setAsFirstSuggestion(nameInfos, i.title.toString()));
         }
         if (DEBUG) {
-            Log.d(TAG, "getSuggestedFolderName:" + Arrays.toString(nameInfos));
+            Log.d(TAG, "getSuggestedFolderName:" + nameInfos.toString());
         }
     }
 
@@ -138,39 +138,37 @@
                 .findAny();
     }
 
-    private void setAsFirstSuggestion(FolderNameInfo[] nameInfos, CharSequence label) {
-        if (nameInfos.length == 0 || contains(nameInfos, label)) {
+    private void setAsFirstSuggestion(FolderNameInfos nameInfos, CharSequence label) {
+        if (nameInfos == null || nameInfos.contains(label)) {
             return;
         }
-        for (int i = nameInfos.length - 1; i > 0; i--) {
-            if (nameInfos[i - 1] != null && !TextUtils.isEmpty(nameInfos[i - 1].getLabel())) {
-                nameInfos[i] = nameInfos[i - 1];
+        nameInfos.setStatus(FolderNameInfos.HAS_PRIMARY);
+        nameInfos.setStatus(FolderNameInfos.HAS_SUGGESTIONS);
+        CharSequence[] labels = nameInfos.getLabels();
+        Float[] scores = nameInfos.getScores();
+        for (int i = labels.length - 1; i > 0; i--) {
+            if (labels[i - 1] != null && !TextUtils.isEmpty(labels[i - 1])) {
+                nameInfos.setLabel(i, labels[i - 1], scores[i - 1]);
             }
         }
-        nameInfos[0] = new FolderNameInfo(label, 1.0);
+        nameInfos.setLabel(0, label, 1.0f);
     }
 
-    private void setAsLastSuggestion(FolderNameInfo[] nameInfos, CharSequence label) {
-        if (nameInfos.length == 0 || contains(nameInfos, label)) {
+    private void setAsLastSuggestion(FolderNameInfos nameInfos, CharSequence label) {
+        if (nameInfos == null || nameInfos.contains(label)) {
             return;
         }
-
-        for (int i = 0; i < nameInfos.length; i++) {
-            if (nameInfos[i] == null || TextUtils.isEmpty(nameInfos[i].getLabel())) {
-                nameInfos[i] = new FolderNameInfo(label, 1.0);
+        nameInfos.setStatus(FolderNameInfos.HAS_PRIMARY);
+        nameInfos.setStatus(FolderNameInfos.HAS_SUGGESTIONS);
+        CharSequence[] labels = nameInfos.getLabels();
+        for (int i = 0; i < labels.length; i++) {
+            if (labels[i] == null || TextUtils.isEmpty(labels[i])) {
+                nameInfos.setLabel(i, label, 1.0f);
                 return;
             }
         }
         // Overwrite the last suggestion.
-        int lastIndex = nameInfos.length - 1;
-        nameInfos[lastIndex] = new FolderNameInfo(label, 1.0);
-    }
-
-    private boolean contains(FolderNameInfo[] nameInfos, CharSequence label) {
-        return Arrays.stream(nameInfos)
-                .filter(Objects::nonNull)
-                .anyMatch(nameInfo -> nameInfo.getLabel().toString().equalsIgnoreCase(
-                        label.toString()));
+        nameInfos.setLabel(labels.length - 1, label, 1.0f);
     }
 
     private class FolderNameWorker extends BaseModelUpdateTask {
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index f2073ef..102ec31 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -59,7 +59,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderGridOrganizer;
-import com.android.launcher3.folder.FolderNameInfo;
+import com.android.launcher3.folder.FolderNameInfos;
 import com.android.launcher3.folder.FolderNameProvider;
 import com.android.launcher3.icons.ComponentWithLabelAndIcon;
 import com.android.launcher3.icons.ComponentWithLabelAndIcon.ComponentWithIconCachingLogic;
@@ -953,13 +953,12 @@
 
         synchronized (mBgDataModel) {
             for (int i = 0; i < mBgDataModel.folders.size(); i++) {
-                FolderNameInfo[] suggestionInfos =
-                        new FolderNameInfo[FolderNameProvider.SUGGEST_MAX];
+                FolderNameInfos suggestionInfos = new FolderNameInfos();
                 FolderInfo info = mBgDataModel.folders.valueAt(i);
                 if (info.suggestedFolderNames == null) {
                     provider.getSuggestedFolderName(mApp.getContext(), info.contents,
                             suggestionInfos);
-                    info.suggestedFolderNames = new Intent().putExtra("suggest", suggestionInfos);
+                    info.suggestedFolderNames = suggestionInfos;
                 }
             }
         }
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 08eb383..ecd18ce 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -29,17 +29,12 @@
 import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
 import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_SUGGESTED;
 
-import static java.util.Arrays.stream;
-import static java.util.Optional.ofNullable;
-
-import android.content.Intent;
 import android.os.Process;
-import android.text.TextUtils;
 
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.folder.FolderNameInfo;
+import com.android.launcher3.folder.FolderNameInfos;
 import com.android.launcher3.logger.LauncherAtom;
 import com.android.launcher3.logger.LauncherAtom.FromState;
 import com.android.launcher3.logger.LauncherAtom.ToState;
@@ -51,8 +46,6 @@
 import com.android.launcher3.util.ContentWriter;
 
 import java.util.ArrayList;
-import java.util.Objects;
-import java.util.Optional;
 import java.util.OptionalInt;
 import java.util.stream.IntStream;
 
@@ -85,7 +78,7 @@
 
     public int options;
 
-    public Intent suggestedFolderNames;
+    public FolderNameInfos suggestedFolderNames;
 
     /**
      * The apps and shortcuts
@@ -224,17 +217,16 @@
     public OptionalInt getAcceptedSuggestionIndex() {
         String newLabel = checkNotNull(title,
                 "Expected valid folder label, but found null").toString();
-        return getSuggestedLabels()
-                .map(suggestionsArray ->
-                        IntStream.range(0, suggestionsArray.length)
-                                .filter(
-                                        index -> !isEmpty(suggestionsArray[index])
-                                                && newLabel.equalsIgnoreCase(
-                                                suggestionsArray[index]))
-                                .sequential()
-                                .findFirst()
-                ).orElse(OptionalInt.empty());
-
+        if (suggestedFolderNames == null || !suggestedFolderNames.hasSuggestions()) {
+            return OptionalInt.empty();
+        }
+        CharSequence[] labels = suggestedFolderNames.getLabels();
+        return IntStream.range(0, labels.length)
+                .filter(index -> !isEmpty(labels[index])
+                        && newLabel.equalsIgnoreCase(
+                        labels[index].toString()))
+                .sequential()
+                .findFirst();
     }
 
     /**
@@ -264,19 +256,15 @@
                     : LauncherAtom.ToState.TO_EMPTY_WITH_SUGGESTIONS_DISABLED;
         }
 
-        Optional<String[]> suggestedLabels = getSuggestedLabels();
-        boolean isEmptySuggestions = suggestedLabels
-                .map(labels -> stream(labels).allMatch(TextUtils::isEmpty))
-                .orElse(true);
-        if (isEmptySuggestions) {
+        // TODO: if suggestedFolderNames is null then it infrastructure issue, not
+        // ranking issue. We should log these appropriately.
+        if (suggestedFolderNames == null || !suggestedFolderNames.hasSuggestions()) {
             return title.length() > 0
                     ? LauncherAtom.ToState.TO_CUSTOM_WITH_EMPTY_SUGGESTIONS
                     : LauncherAtom.ToState.TO_EMPTY_WITH_EMPTY_SUGGESTIONS;
         }
 
-        boolean hasValidPrimary = suggestedLabels
-                .map(labels -> !isEmpty(labels[0]))
-                .orElse(false);
+        boolean hasValidPrimary = suggestedFolderNames != null && suggestedFolderNames.hasPrimary();
         if (title.length() == 0) {
             return hasValidPrimary ? LauncherAtom.ToState.TO_EMPTY_WITH_VALID_PRIMARY
                     : LauncherAtom.ToState.TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY;
@@ -306,20 +294,6 @@
         return LauncherAtom.ToState.TO_STATE_UNSPECIFIED;
     }
 
-    private Optional<String[]> getSuggestedLabels() {
-        return ofNullable(suggestedFolderNames)
-                .map(folderNames ->
-                        (FolderNameInfo[])
-                                folderNames.getParcelableArrayExtra(EXTRA_FOLDER_SUGGESTIONS))
-                .map(folderNameInfoArray ->
-                        stream(folderNameInfoArray)
-                                .filter(Objects::nonNull)
-                                .map(FolderNameInfo::getLabel)
-                                .filter(Objects::nonNull)
-                                .map(CharSequence::toString)
-                                .toArray(String[]::new));
-    }
-
     /**
      * Returns {@link LauncherLogProto.LauncherEvent} to log current folder label info.
      *