Loading protos/launcher_atom.proto +15 −2 Original line number Diff line number Diff line Loading @@ -96,8 +96,21 @@ enum Attribute { ADD_TO_HOMESCREEN = 6; // play install + launcher home setting ALLAPPS_PREDICTION = 7; // from prediction bar in all apps container HOTSEAT_PREDICTION = 8; // from prediction bar in hotseat container SUGGESTED_LABEL = 9; // folder icon's label was suggested MANUAL_LABEL = 10; // folder icon's label was manually edited // Folder's label is one of the non-empty suggested values. SUGGESTED_LABEL = 9; // Folder's label is non-empty, manually entered by the user // and different from any of suggested values. MANUAL_LABEL = 10; // Folder's label is not yet assigned( i.e., title == null). // Eligible for auto-labeling. UNLABELED = 11; // Folder's label is empty(i.e., title == ""). // Not eligible for auto-labeling. EMPTY_LABEL = 12; } // Main app icons Loading quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java +1 −1 Original line number Diff line number Diff line Loading @@ -114,9 +114,9 @@ public class HotseatEduController { if (!putIntoFolder.isEmpty()) { ItemInfo firstItem = putIntoFolder.get(0); FolderInfo folderInfo = new FolderInfo(); folderInfo.setTitle(""); mLauncher.getModelWriter().addItemToDatabase(folderInfo, firstItem.container, firstItem.screenId, firstItem.cellX, firstItem.cellY); folderInfo.setTitle("", mLauncher.getModelWriter()); folderInfo.contents.addAll(putIntoFolder); for (int i = 0; i < folderInfo.contents.size(); i++) { ItemInfo item = folderInfo.contents.get(i); Loading src/com/android/launcher3/folder/Folder.java +1 −5 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTI 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 android.animation.Animator; import android.animation.AnimatorListenerAdapter; Loading Loading @@ -339,11 +338,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo if (DEBUG) { Log.d(TAG, "onBackKey newTitle=" + newTitle); } mInfo.setTitle(newTitle); mInfo.setOption(FLAG_MANUAL_FOLDER_NAME, !mInfo.getAcceptedSuggestionIndex().isPresent(), mLauncher.getModelWriter()); mInfo.setTitle(newTitle, mLauncher.getModelWriter()); mFolderIcon.onTitleChanged(newTitle); mLauncher.getModelWriter().updateItemInDatabase(mInfo); if (TextUtils.isEmpty(mInfo.title)) { mFolderName.setHint(R.string.folder_hint_text); Loading src/com/android/launcher3/folder/FolderIcon.java +3 −6 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.launcher3.folder; import static android.text.TextUtils.isEmpty; 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_AUTO_LABELED; Loading Loading @@ -72,6 +70,7 @@ import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo.FolderListener; import com.android.launcher3.model.data.FolderInfo.LabelState; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.touch.ItemClickHandler; Loading Loading @@ -443,8 +442,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!FeatureFlags.FOLDER_NAME_SUGGEST.get()) { return; } if (!isEmpty(mFolderName.getText().toString()) || mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) { if (!mInfo.getLabelState().equals(LabelState.UNLABELED)) { return; } if (nameInfos == null || !nameInfos.hasSuggestions()) { Loading @@ -464,10 +462,9 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel CharSequence newTitle = nameInfos.getLabels()[0]; FromState fromState = mInfo.getFromLabelState(); mInfo.setTitle(newTitle); mInfo.setTitle(newTitle, mFolder.mLauncher.getModelWriter()); onTitleChanged(mInfo.title); mFolder.mFolderName.setText(mInfo.title); mFolder.mLauncher.getModelWriter().updateItemInDatabase(mInfo); // Logging for folder creation flow StatsLogManager.newInstance(getContext()).logger() Loading src/com/android/launcher3/model/data/FolderInfo.java +69 −11 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ 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.logger.LauncherAtom.Attribute.EMPTY_LABEL; import static com.android.launcher3.logger.LauncherAtom.Attribute.MANUAL_LABEL; import static com.android.launcher3.logger.LauncherAtom.Attribute.SUGGESTED_LABEL; import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM; Loading @@ -31,11 +32,14 @@ import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolder import android.os.Process; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderNameInfos; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.logger.LauncherAtom.Attribute; import com.android.launcher3.logger.LauncherAtom.FromState; import com.android.launcher3.logger.LauncherAtom.ToState; import com.android.launcher3.model.ModelWriter; Loading Loading @@ -74,6 +78,30 @@ public class FolderInfo extends ItemInfo { public static final int FLAG_MANUAL_FOLDER_NAME = 0x00000008; /** * Different states of folder label. */ public enum LabelState { // Folder's label is not yet assigned( i.e., title == null). Eligible for auto-labeling. UNLABELED(Attribute.UNLABELED), // Folder's label is empty(i.e., title == ""). Not eligible for auto-labeling. EMPTY(EMPTY_LABEL), // Folder's label is one of the non-empty suggested values. SUGGESTED(SUGGESTED_LABEL), // Folder's label is non-empty, manually entered by the user // and different from any of suggested values. MANUAL(MANUAL_LABEL); private final LauncherAtom.Attribute mLogAttribute; LabelState(Attribute logAttribute) { this.mLogAttribute = logAttribute; } } public static final String EXTRA_FOLDER_SUGGESTIONS = "suggest"; public int options; Loading Loading @@ -176,8 +204,7 @@ public class FolderInfo extends ItemInfo { @Override protected String dumpProperties() { return super.dumpProperties() + " manuallyTypedTitle=" + hasOption(FLAG_MANUAL_FOLDER_NAME); return String.format("%s; labelState=%s", super.dumpProperties(), getLabelState()); } @Override Loading @@ -185,14 +212,41 @@ public class FolderInfo extends ItemInfo { return getDefaultItemInfoBuilder() .setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size())) .setRank(rank) .setAttribute(hasOption(FLAG_MANUAL_FOLDER_NAME) ? MANUAL_LABEL : SUGGESTED_LABEL) .setAttribute(getLabelState().mLogAttribute) .setContainerInfo(getContainerInfo()) .build(); } @Override public void setTitle(CharSequence title) { public void setTitle(@Nullable CharSequence title, ModelWriter modelWriter) { // Updating label from null to empty is considered as false touch. // Retaining null title(ie., UNLABELED state) allows auto-labeling when new items added. if (isEmpty(title) && this.title == null) { return; } // Updating title to same value does not change any states. if (title != null && title == this.title) { return; } this.title = title; LabelState newLabelState = title == null ? LabelState.UNLABELED : title.length() == 0 ? LabelState.EMPTY : getAcceptedSuggestionIndex().isPresent() ? LabelState.SUGGESTED : LabelState.MANUAL; setOption(FLAG_MANUAL_FOLDER_NAME, newLabelState.equals(LabelState.MANUAL), modelWriter); } /** * Returns current state of the current folder label. */ public LabelState getLabelState() { return title == null ? LabelState.UNLABELED : title.length() == 0 ? LabelState.EMPTY : hasOption(FLAG_MANUAL_FOLDER_NAME) ? LabelState.MANUAL : LabelState.SUGGESTED; } @Override Loading Loading @@ -233,13 +287,17 @@ public class FolderInfo extends ItemInfo { * Returns {@link FromState} based on current {@link #title}. */ public LauncherAtom.FromState getFromLabelState() { return title == null ? LauncherAtom.FromState.FROM_STATE_UNSPECIFIED : title.length() == 0 ? LauncherAtom.FromState.FROM_EMPTY : hasOption(FLAG_MANUAL_FOLDER_NAME) ? LauncherAtom.FromState.FROM_CUSTOM : LauncherAtom.FromState.FROM_SUGGESTED; switch (getLabelState()){ case EMPTY: return LauncherAtom.FromState.FROM_EMPTY; case MANUAL: return LauncherAtom.FromState.FROM_CUSTOM; case SUGGESTED: return LauncherAtom.FromState.FROM_SUGGESTED; case UNLABELED: default: return LauncherAtom.FromState.FROM_STATE_UNSPECIFIED; } } /** Loading Loading
protos/launcher_atom.proto +15 −2 Original line number Diff line number Diff line Loading @@ -96,8 +96,21 @@ enum Attribute { ADD_TO_HOMESCREEN = 6; // play install + launcher home setting ALLAPPS_PREDICTION = 7; // from prediction bar in all apps container HOTSEAT_PREDICTION = 8; // from prediction bar in hotseat container SUGGESTED_LABEL = 9; // folder icon's label was suggested MANUAL_LABEL = 10; // folder icon's label was manually edited // Folder's label is one of the non-empty suggested values. SUGGESTED_LABEL = 9; // Folder's label is non-empty, manually entered by the user // and different from any of suggested values. MANUAL_LABEL = 10; // Folder's label is not yet assigned( i.e., title == null). // Eligible for auto-labeling. UNLABELED = 11; // Folder's label is empty(i.e., title == ""). // Not eligible for auto-labeling. EMPTY_LABEL = 12; } // Main app icons Loading
quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java +1 −1 Original line number Diff line number Diff line Loading @@ -114,9 +114,9 @@ public class HotseatEduController { if (!putIntoFolder.isEmpty()) { ItemInfo firstItem = putIntoFolder.get(0); FolderInfo folderInfo = new FolderInfo(); folderInfo.setTitle(""); mLauncher.getModelWriter().addItemToDatabase(folderInfo, firstItem.container, firstItem.screenId, firstItem.cellX, firstItem.cellY); folderInfo.setTitle("", mLauncher.getModelWriter()); folderInfo.contents.addAll(putIntoFolder); for (int i = 0; i < folderInfo.contents.size(); i++) { ItemInfo item = folderInfo.contents.get(i); Loading
src/com/android/launcher3/folder/Folder.java +1 −5 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTI 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 android.animation.Animator; import android.animation.AnimatorListenerAdapter; Loading Loading @@ -339,11 +338,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo if (DEBUG) { Log.d(TAG, "onBackKey newTitle=" + newTitle); } mInfo.setTitle(newTitle); mInfo.setOption(FLAG_MANUAL_FOLDER_NAME, !mInfo.getAcceptedSuggestionIndex().isPresent(), mLauncher.getModelWriter()); mInfo.setTitle(newTitle, mLauncher.getModelWriter()); mFolderIcon.onTitleChanged(newTitle); mLauncher.getModelWriter().updateItemInDatabase(mInfo); if (TextUtils.isEmpty(mInfo.title)) { mFolderName.setHint(R.string.folder_hint_text); Loading
src/com/android/launcher3/folder/FolderIcon.java +3 −6 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.launcher3.folder; import static android.text.TextUtils.isEmpty; 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_AUTO_LABELED; Loading Loading @@ -72,6 +70,7 @@ import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.FolderInfo.FolderListener; import com.android.launcher3.model.data.FolderInfo.LabelState; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.touch.ItemClickHandler; Loading Loading @@ -443,8 +442,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!FeatureFlags.FOLDER_NAME_SUGGEST.get()) { return; } if (!isEmpty(mFolderName.getText().toString()) || mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) { if (!mInfo.getLabelState().equals(LabelState.UNLABELED)) { return; } if (nameInfos == null || !nameInfos.hasSuggestions()) { Loading @@ -464,10 +462,9 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel CharSequence newTitle = nameInfos.getLabels()[0]; FromState fromState = mInfo.getFromLabelState(); mInfo.setTitle(newTitle); mInfo.setTitle(newTitle, mFolder.mLauncher.getModelWriter()); onTitleChanged(mInfo.title); mFolder.mFolderName.setText(mInfo.title); mFolder.mLauncher.getModelWriter().updateItemInDatabase(mInfo); // Logging for folder creation flow StatsLogManager.newInstance(getContext()).logger() Loading
src/com/android/launcher3/model/data/FolderInfo.java +69 −11 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ 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.logger.LauncherAtom.Attribute.EMPTY_LABEL; import static com.android.launcher3.logger.LauncherAtom.Attribute.MANUAL_LABEL; import static com.android.launcher3.logger.LauncherAtom.Attribute.SUGGESTED_LABEL; import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM; Loading @@ -31,11 +32,14 @@ import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolder import android.os.Process; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.folder.FolderNameInfos; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.logger.LauncherAtom.Attribute; import com.android.launcher3.logger.LauncherAtom.FromState; import com.android.launcher3.logger.LauncherAtom.ToState; import com.android.launcher3.model.ModelWriter; Loading Loading @@ -74,6 +78,30 @@ public class FolderInfo extends ItemInfo { public static final int FLAG_MANUAL_FOLDER_NAME = 0x00000008; /** * Different states of folder label. */ public enum LabelState { // Folder's label is not yet assigned( i.e., title == null). Eligible for auto-labeling. UNLABELED(Attribute.UNLABELED), // Folder's label is empty(i.e., title == ""). Not eligible for auto-labeling. EMPTY(EMPTY_LABEL), // Folder's label is one of the non-empty suggested values. SUGGESTED(SUGGESTED_LABEL), // Folder's label is non-empty, manually entered by the user // and different from any of suggested values. MANUAL(MANUAL_LABEL); private final LauncherAtom.Attribute mLogAttribute; LabelState(Attribute logAttribute) { this.mLogAttribute = logAttribute; } } public static final String EXTRA_FOLDER_SUGGESTIONS = "suggest"; public int options; Loading Loading @@ -176,8 +204,7 @@ public class FolderInfo extends ItemInfo { @Override protected String dumpProperties() { return super.dumpProperties() + " manuallyTypedTitle=" + hasOption(FLAG_MANUAL_FOLDER_NAME); return String.format("%s; labelState=%s", super.dumpProperties(), getLabelState()); } @Override Loading @@ -185,14 +212,41 @@ public class FolderInfo extends ItemInfo { return getDefaultItemInfoBuilder() .setFolderIcon(LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size())) .setRank(rank) .setAttribute(hasOption(FLAG_MANUAL_FOLDER_NAME) ? MANUAL_LABEL : SUGGESTED_LABEL) .setAttribute(getLabelState().mLogAttribute) .setContainerInfo(getContainerInfo()) .build(); } @Override public void setTitle(CharSequence title) { public void setTitle(@Nullable CharSequence title, ModelWriter modelWriter) { // Updating label from null to empty is considered as false touch. // Retaining null title(ie., UNLABELED state) allows auto-labeling when new items added. if (isEmpty(title) && this.title == null) { return; } // Updating title to same value does not change any states. if (title != null && title == this.title) { return; } this.title = title; LabelState newLabelState = title == null ? LabelState.UNLABELED : title.length() == 0 ? LabelState.EMPTY : getAcceptedSuggestionIndex().isPresent() ? LabelState.SUGGESTED : LabelState.MANUAL; setOption(FLAG_MANUAL_FOLDER_NAME, newLabelState.equals(LabelState.MANUAL), modelWriter); } /** * Returns current state of the current folder label. */ public LabelState getLabelState() { return title == null ? LabelState.UNLABELED : title.length() == 0 ? LabelState.EMPTY : hasOption(FLAG_MANUAL_FOLDER_NAME) ? LabelState.MANUAL : LabelState.SUGGESTED; } @Override Loading Loading @@ -233,13 +287,17 @@ public class FolderInfo extends ItemInfo { * Returns {@link FromState} based on current {@link #title}. */ public LauncherAtom.FromState getFromLabelState() { return title == null ? LauncherAtom.FromState.FROM_STATE_UNSPECIFIED : title.length() == 0 ? LauncherAtom.FromState.FROM_EMPTY : hasOption(FLAG_MANUAL_FOLDER_NAME) ? LauncherAtom.FromState.FROM_CUSTOM : LauncherAtom.FromState.FROM_SUGGESTED; switch (getLabelState()){ case EMPTY: return LauncherAtom.FromState.FROM_EMPTY; case MANUAL: return LauncherAtom.FromState.FROM_CUSTOM; case SUGGESTED: return LauncherAtom.FromState.FROM_SUGGESTED; case UNLABELED: default: return LauncherAtom.FromState.FROM_STATE_UNSPECIFIED; } } /** Loading