Add LAUNCHER_FOLDER_LABEL_CHANGED events for folder label updates.
Sample Logs for all update combinations: https://docs.google.com/document/d/1CBP2yTcXdFhPdNG5ZmWFKSgd8mDbMevY-akVlUXPLDo/edit#bookmark=id.7y1p8n2dz8ge
Bug: 155410872
Bug: 152978018
Change-Id: I296b124b16aa07878f2cf7b74ab91f13b8e6cfbf
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 19f7213..f1b71e8 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -99,13 +99,14 @@
optional int32 cardinality = 1;
// State of the folder label before the event.
- optional FromState from_state = 2;
+ optional FromState from_label_state = 2;
// State of the folder label after the event.
- optional ToState to_state = 3;
+ optional ToState to_label_state = 3;
- // Populated only when folder label was suggested.
- optional string label = 4;
+ // Details about actual folder label.
+ // Populated when folder label is not a PII.
+ optional string label_info = 4;
}
//////////////////////////////////////////////
@@ -131,70 +132,77 @@
}
}
-// Represents state of FolderLabel before editing.
+// Represents state of EditText field before update.
enum FromState {
// Default value.
+ // Used when a FromState is not applicable, for example, during folder creation.
FROM_STATE_UNSPECIFIED = 0;
- // FolderLabel was empty.
+ // EditText was empty.
+ // Eg: When a folder label is updated from empty string.
FROM_EMPTY = 1;
- // FolderLabel was non-empty and manually entered by the user.
+ // EditText was non-empty and manually entered by the user.
+ // Eg: When a folder label is updated from a user-entered value.
FROM_CUSTOM = 2;
- // FolderLabel was non-empty and one of the suggestions.
+ // EditText was non-empty and one of the suggestions.
+ // Eg: When a folder label is updated from a suggested value.
FROM_SUGGESTED = 3;
}
-// Represents state of FolderLabel after editing.
+// Represents state of EditText field after update.
enum ToState {
// Default value.
+ // Used when ToState is not applicable, for example, when folder label is updated to a different
+ // value when folder label suggestion feature is disabled.
TO_STATE_UNSPECIFIED = 0;
- // User attempted to change the folder label, but was not changed.
+
+ // User attempted to change the EditText, but was not changed.
UNCHANGED = 1;
// New label matches with primary(aka top) suggestion.
TO_SUGGESTION0 = 2;
- // New label matches with second top suggestion even though the top suggestion was non-empty.
+ // New value matches with second top suggestion even though the top suggestion was non-empty.
TO_SUGGESTION1_WITH_VALID_PRIMARY = 3;
- // New label matches with second top suggestion given that top suggestion was empty.
+ // New value matches with second top suggestion given that top suggestion was empty.
TO_SUGGESTION1_WITH_EMPTY_PRIMARY = 4;
- // New label matches with third top suggestion even though the top suggestion was non-empty.
+ // New value matches with third top suggestion even though the top suggestion was non-empty.
TO_SUGGESTION2_WITH_VALID_PRIMARY = 5;
- // New label matches with third top suggestion given that top suggestion was empty.
+ // New value matches with third top suggestion given that top suggestion was empty.
TO_SUGGESTION2_WITH_EMPTY_PRIMARY = 6;
- // New label matches with 4th top suggestion even though the top suggestion was non-empty.
+ // New value matches with 4th top suggestion even though the top suggestion was non-empty.
TO_SUGGESTION3_WITH_VALID_PRIMARY = 7;
- // New label matches with 4th top suggestion given that top suggestion was empty.
+ // New value matches with 4th top suggestion given that top suggestion was empty.
TO_SUGGESTION3_WITH_EMPTY_PRIMARY = 8;
- // New label is empty even though the top suggestion was non-empty.
+ // New value is empty even though the top suggestion was non-empty.
TO_EMPTY_WITH_VALID_PRIMARY = 9;
- // New label is empty given that top suggestion was empty.
+ // New value is empty given that top suggestion was empty.
TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY = 10;
- // New label is empty given that no suggestions were provided.
+ // New value is empty given that no suggestions were provided.
TO_EMPTY_WITH_EMPTY_SUGGESTIONS = 11;
- // New label is empty given that suggestions feature was disabled.
+ // New value is empty given that suggestions feature was disabled.
TO_EMPTY_WITH_SUGGESTIONS_DISABLED = 12;
- // New label is non-empty and does not match with any of the suggestions even though the top suggestion was non-empty.
+ // New value is non-empty and does not match with any of the suggestions even though the top suggestion was non-empty.
TO_CUSTOM_WITH_VALID_PRIMARY = 13;
- // New label is non-empty and not match with any suggestions given that top suggestion was empty.
+ // New value is non-empty and not match with any suggestions given that top suggestion was empty.
TO_CUSTOM_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY = 14;
- // New label is non-empty and also no suggestions were provided.
+ // New value is non-empty and also no suggestions were provided.
TO_CUSTOM_WITH_EMPTY_SUGGESTIONS = 15;
- // New label is non-empty and also suggestions feature was disable.
+ // New value is non-empty and also suggestions feature was disable.
TO_CUSTOM_WITH_SUGGESTIONS_DISABLED = 16;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index 7f8f0a0..e4d0adf 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -121,7 +121,7 @@
if (!putIntoFolder.isEmpty()) {
ItemInfo firstItem = putIntoFolder.get(0);
FolderInfo folderInfo = new FolderInfo();
- folderInfo.title = "";
+ folderInfo.setTitle("");
mLauncher.getModelWriter().addItemToDatabase(folderInfo, firstItem.container,
firstItem.screenId, firstItem.cellX, firstItem.cellY);
folderInfo.contents.addAll(putIntoFolder);
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 29a737c..f7fe535 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -24,6 +24,8 @@
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
+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;
@@ -196,6 +198,7 @@
@Thunk int mScrollHintDir = SCROLL_NONE;
@Thunk int mCurrentScrollDir = SCROLL_NONE;
+ private StatsLogManager mStatsLogManager;
/**
* Used to inflate the Workspace from XML.
@@ -208,10 +211,12 @@
setAlwaysDrawnWithCacheEnabled(false);
mLauncher = Launcher.getLauncher(context);
+ mStatsLogManager = StatsLogManager.newInstance(context);
// We need this view to be focusable in touch mode so that when text editing of the folder
// name is complete, we have something to focus on, thus hiding the cursor and giving
// reliable behavior when clicking the text field (since it will always gain focus on click).
setFocusableInTouchMode(true);
+
}
@Override
@@ -329,8 +334,8 @@
if (DEBUG) {
Log.d(TAG, "onBackKey newTitle=" + newTitle);
}
- mInfo.previousTitle = mInfo.title;
- mInfo.title = newTitle;
+ mInfo.setTitle(newTitle);
+ mInfo.fromCustom = mInfo.hasOption(FLAG_MANUAL_FOLDER_NAME);
mInfo.setOption(FLAG_MANUAL_FOLDER_NAME, !mInfo.getAcceptedSuggestionIndex().isPresent(),
mLauncher.getModelWriter());
mFolderIcon.onTitleChanged(newTitle);
@@ -1326,10 +1331,8 @@
if (d.stateAnnouncer != null) {
d.stateAnnouncer.completeAction(R.string.item_moved);
}
- StatsLogManager.newInstance(getContext())
- .log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED,
- d.logInstanceId,
- d.dragInfo.buildProto(mInfo));
+ mStatsLogManager
+ .log(LAUNCHER_ITEM_DROP_COMPLETED, d.logInstanceId, d.dragInfo.buildProto(mInfo));
}
// This is used so the item doesn't immediately appear in the folder when added. In one case
@@ -1434,6 +1437,8 @@
if (hasFocus) {
startEditingFolderName();
} else {
+ mStatsLogManager.log(LAUNCHER_FOLDER_LABEL_UPDATED, mInfo.buildProto());
+ logFolderLabelState();
mFolderName.dispatchBackKey();
}
}
@@ -1631,4 +1636,15 @@
public FolderPagedView getContent() {
return mContent;
}
+
+ /**
+ * Logs current folder label info.
+ *
+ * @deprecated This method is only used for log validation and soon will be removed.
+ */
+ @Deprecated
+ public void logFolderLabelState() {
+ mLauncher.getUserEventDispatcher()
+ .logLauncherEvent(mInfo.getFolderLabelStateLauncherEvent());
+ }
}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index bb358ab..153d6bc 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -20,7 +20,7 @@
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_CHANGED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -429,6 +429,7 @@
mPreviewItemManager.hidePreviewItem(finalIndex, false);
mFolder.showItem(item);
setLabelSuggestion(nameInfos, instanceId);
+ mFolder.logFolderLabelState();
invalidate();
}, DROP_IN_ANIMATION_DURATION);
}
@@ -447,10 +448,9 @@
if (nameInfos == null || nameInfos[0] == null || isEmpty(nameInfos[0].getLabel())) {
return;
}
- mInfo.previousTitle = mInfo.title;
- mInfo.title = nameInfos[0].getLabel();
+ mInfo.setTitle(nameInfos[0].getLabel());
StatsLogManager.newInstance(getContext())
- .log(LAUNCHER_FOLDER_LABEL_CHANGED, instanceId, mInfo.getFolderIconAtom());
+ .log(LAUNCHER_FOLDER_LABEL_UPDATED, instanceId, mInfo.buildProto());
onTitleChanged(mInfo.title);
mFolder.mFolderName.setText(mInfo.title);
mFolder.mLauncher.getModelWriter().updateItemInDatabase(mInfo);
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index ee9322b..b240f0b 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -57,9 +57,9 @@
+ "resulting in a new folder creation")
LAUNCHER_ITEM_DROP_FOLDER_CREATED(386),
- @LauncherUiEvent(doc = "A dragged launcher item is successfully dropped on another item "
- + "resulting in new folder creation")
- LAUNCHER_FOLDER_LABEL_CHANGED(460),
+ @LauncherUiEvent(doc = "User action resulted in or manually updated the folder label to "
+ + "new/same value.")
+ LAUNCHER_FOLDER_LABEL_UPDATED(460),
@LauncherUiEvent(doc = "A dragged item is dropped on 'Remove' button in the target bar")
LAUNCHER_ITEM_DROPPED_ON_REMOVE(465),
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index fd024f4..096743a 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -20,6 +20,13 @@
import static androidx.core.util.Preconditions.checkNotNull;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM;
+import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_EMPTY;
+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;
@@ -32,13 +39,20 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderNameInfo;
import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logger.LauncherAtom.FromState;
+import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.model.ModelWriter;
+import com.android.launcher3.userevent.LauncherLogProto;
+import com.android.launcher3.userevent.LauncherLogProto.Target;
+import com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState;
+import com.android.launcher3.userevent.LauncherLogProto.Target.ToFolderLabelState;
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.StringJoiner;
import java.util.stream.IntStream;
@@ -72,9 +86,19 @@
public Intent suggestedFolderNames;
- // When title changes, previous title is stored.
+ // Represents the title before current.
// Primarily used for logging purpose.
- public CharSequence previousTitle;
+ private CharSequence mPreviousTitle;
+
+ // True if the title before was manually entered, suggested otherwise.
+ // Primarily used for logging purpose.
+ public boolean fromCustom;
+
+ /**
+ * Used for separating {@link #mPreviousTitle} and {@link #title} when concatenating them
+ * for logging.
+ */
+ private static final CharSequence FOLDER_LABEL_DELIMITER = "=>";
/**
* The apps and shortcuts
@@ -179,9 +203,20 @@
@Override
public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
return getDefaultItemInfoBuilder()
- .setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size()))
- .setContainerInfo(getContainerInfo())
- .build();
+ .setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size()))
+ .setRank(rank)
+ .setContainerInfo(getContainerInfo())
+ .build();
+ }
+
+ @Override
+ public void setTitle(CharSequence title) {
+ mPreviousTitle = this.title;
+ this.title = title;
+ }
+
+ public CharSequence getPreviousTitle() {
+ return mPreviousTitle;
}
@Override
@@ -193,19 +228,30 @@
}
/**
- * Returns {@link LauncherAtom.FolderIcon} wrapped as {@link LauncherAtom.ItemInfo} for logging
- * into Westworld.
- *
+ * Returns {@link LauncherAtom.FolderIcon} wrapped as {@link LauncherAtom.ItemInfo} for logging.
*/
- public LauncherAtom.ItemInfo getFolderIconAtom() {
- LauncherAtom.ToState toFolderLabelState = getToFolderLabelState();
+ @Override
+ public LauncherAtom.ItemInfo buildProto() {
+ FromState fromFolderLabelState = getFromFolderLabelState();
+ ToState toFolderLabelState = getToFolderLabelState();
LauncherAtom.FolderIcon.Builder folderIconBuilder = LauncherAtom.FolderIcon.newBuilder()
.setCardinality(contents.size())
- .setFromState(getFromFolderLabelState())
- .setToState(toFolderLabelState);
- if (toFolderLabelState.toString().startsWith("TO_SUGGESTION")) {
- folderIconBuilder.setLabel(title.toString());
+ .setFromLabelState(fromFolderLabelState)
+ .setToLabelState(toFolderLabelState);
+
+ // If the folder label is suggested, it is logged to improve prediction model.
+ // When both old and new labels are logged together delimiter is used.
+ StringJoiner labelInfoBuilder = new StringJoiner(FOLDER_LABEL_DELIMITER);
+ if (fromFolderLabelState.equals(FromState.FROM_SUGGESTED)) {
+ labelInfoBuilder.add(mPreviousTitle);
}
+ if (toFolderLabelState.toString().startsWith("TO_SUGGESTION")) {
+ labelInfoBuilder.add(title);
+ }
+ if (labelInfoBuilder.length() > 0) {
+ folderIconBuilder.setLabelInfo(labelInfoBuilder.toString());
+ }
+
return getDefaultItemInfoBuilder()
.setFolderIcon(folderIconBuilder)
.setContainerInfo(getContainerInfo())
@@ -236,7 +282,7 @@
return LauncherAtom.ToState.TO_STATE_UNSPECIFIED;
}
- if (title.equals(previousTitle)) {
+ if (title.equals(mPreviousTitle)) {
return LauncherAtom.ToState.UNCHANGED;
}
@@ -290,13 +336,13 @@
}
private LauncherAtom.FromState getFromFolderLabelState() {
- return previousTitle == null
+ return mPreviousTitle == null
? LauncherAtom.FromState.FROM_STATE_UNSPECIFIED
- : previousTitle.toString().isEmpty()
- ? LauncherAtom.FromState.FROM_EMPTY
- : hasOption(FLAG_MANUAL_FOLDER_NAME)
- ? LauncherAtom.FromState.FROM_CUSTOM
- : LauncherAtom.FromState.FROM_SUGGESTED;
+ : mPreviousTitle.length() == 0
+ ? LauncherAtom.FromState.FROM_EMPTY
+ : fromCustom
+ ? LauncherAtom.FromState.FROM_CUSTOM
+ : LauncherAtom.FromState.FROM_SUGGESTED;
}
private Optional<String[]> getSuggestedLabels() {
@@ -312,4 +358,112 @@
.map(CharSequence::toString)
.toArray(String[]::new));
}
+
+ /**
+ * Returns {@link LauncherLogProto.LauncherEvent} to log current folder label info.
+ *
+ * @deprecated This method is used only for validation purpose and soon will be removed.
+ */
+ @Deprecated
+ public LauncherLogProto.LauncherEvent getFolderLabelStateLauncherEvent() {
+ return LauncherLogProto.LauncherEvent.newBuilder()
+ .setAction(LauncherLogProto.Action
+ .newBuilder()
+ .setType(LauncherLogProto.Action.Type.SOFT_KEYBOARD))
+ .addSrcTarget(Target
+ .newBuilder()
+ .setType(Target.Type.ITEM)
+ .setItemType(LauncherLogProto.ItemType.EDITTEXT)
+ .setFromFolderLabelState(convertFolderLabelState(getFromFolderLabelState()))
+ .setToFolderLabelState(convertFolderLabelState(getToFolderLabelState())))
+ .addSrcTarget(Target.newBuilder()
+ .setType(Target.Type.CONTAINER)
+ .setContainerType(LauncherLogProto.ContainerType.FOLDER)
+ .setPageIndex(screenId)
+ .setGridX(cellX)
+ .setGridY(cellY)
+ .setCardinality(contents.size()))
+ .addSrcTarget(newParentContainerTarget())
+ .build();
+ }
+
+ /**
+ * @deprecated This method is used only for validation purpose and soon will be removed.
+ */
+ @Deprecated
+ private Target.Builder newParentContainerTarget() {
+ Target.Builder builder = Target.newBuilder().setType(Target.Type.CONTAINER);
+ switch (container) {
+ case CONTAINER_HOTSEAT:
+ return builder.setContainerType(LauncherLogProto.ContainerType.HOTSEAT);
+ case CONTAINER_DESKTOP:
+ return builder.setContainerType(LauncherLogProto.ContainerType.WORKSPACE);
+ default:
+ throw new AssertionError(String
+ .format("Expected container to be either %s or %s but found %s.",
+ CONTAINER_HOTSEAT,
+ CONTAINER_DESKTOP,
+ container));
+ }
+ }
+
+ /**
+ * @deprecated This method is used only for validation purpose and soon will be removed.
+ */
+ @Deprecated
+ private static FromFolderLabelState convertFolderLabelState(FromState fromState) {
+ switch (fromState) {
+ case FROM_EMPTY:
+ return FROM_EMPTY;
+ case FROM_SUGGESTED:
+ return FROM_SUGGESTED;
+ case FROM_CUSTOM:
+ return FROM_CUSTOM;
+ default:
+ return FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
+ }
+ }
+
+ /**
+ * @deprecated This method is used only for validation purpose and soon will be removed.
+ */
+ @Deprecated
+ private static ToFolderLabelState convertFolderLabelState(ToState toState) {
+ switch (toState) {
+ case UNCHANGED:
+ return ToFolderLabelState.UNCHANGED;
+ case TO_SUGGESTION0:
+ return ToFolderLabelState.TO_SUGGESTION0_WITH_VALID_PRIMARY;
+ case TO_SUGGESTION1_WITH_VALID_PRIMARY:
+ return ToFolderLabelState.TO_SUGGESTION1_WITH_VALID_PRIMARY;
+ case TO_SUGGESTION1_WITH_EMPTY_PRIMARY:
+ return ToFolderLabelState.TO_SUGGESTION1_WITH_EMPTY_PRIMARY;
+ case TO_SUGGESTION2_WITH_VALID_PRIMARY:
+ return ToFolderLabelState.TO_SUGGESTION2_WITH_VALID_PRIMARY;
+ case TO_SUGGESTION2_WITH_EMPTY_PRIMARY:
+ return ToFolderLabelState.TO_SUGGESTION2_WITH_EMPTY_PRIMARY;
+ case TO_SUGGESTION3_WITH_VALID_PRIMARY:
+ return ToFolderLabelState.TO_SUGGESTION3_WITH_VALID_PRIMARY;
+ case TO_SUGGESTION3_WITH_EMPTY_PRIMARY:
+ return ToFolderLabelState.TO_SUGGESTION3_WITH_EMPTY_PRIMARY;
+ case TO_EMPTY_WITH_VALID_PRIMARY:
+ return ToFolderLabelState.TO_EMPTY_WITH_VALID_PRIMARY;
+ case TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY:
+ return ToFolderLabelState.TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY;
+ case TO_EMPTY_WITH_EMPTY_SUGGESTIONS:
+ return ToFolderLabelState.TO_EMPTY_WITH_EMPTY_SUGGESTIONS;
+ case TO_EMPTY_WITH_SUGGESTIONS_DISABLED:
+ return ToFolderLabelState.TO_EMPTY_WITH_SUGGESTIONS_DISABLED;
+ case TO_CUSTOM_WITH_VALID_PRIMARY:
+ return ToFolderLabelState.TO_CUSTOM_WITH_VALID_PRIMARY;
+ case TO_CUSTOM_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY:
+ return ToFolderLabelState.TO_CUSTOM_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY;
+ case TO_CUSTOM_WITH_EMPTY_SUGGESTIONS:
+ return ToFolderLabelState.TO_CUSTOM_WITH_EMPTY_SUGGESTIONS;
+ case TO_CUSTOM_WITH_SUGGESTIONS_DISABLED:
+ return ToFolderLabelState.TO_CUSTOM_WITH_SUGGESTIONS_DISABLED;
+ default:
+ return ToFolderLabelState.TO_FOLDER_LABEL_STATE_UNSPECIFIED;
+ }
+ }
}
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 7611ee7..f2b7e54 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -252,6 +252,13 @@
/**
* Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
*/
+ public LauncherAtom.ItemInfo buildProto() {
+ return buildProto(null);
+ }
+
+ /**
+ * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
+ */
public LauncherAtom.ItemInfo buildProto(FolderInfo fInfo) {
LauncherAtom.ItemInfo.Builder itemBuilder = getDefaultItemInfoBuilder();
Optional<ComponentName> nullableComponent = Optional.ofNullable(getTargetComponent());
@@ -345,4 +352,8 @@
itemInfo.copyFrom(this);
return itemInfo;
}
+
+ public void setTitle(CharSequence title) {
+ this.title = title;
+ }
}