Loading robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java +10 −9 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ */ package com.android.launcher3.folder; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -61,15 +61,16 @@ public final class FolderNameProviderTest { ArrayList<WorkspaceItemInfo> list = new ArrayList<>(); list.add(mItem1); list.add(mItem2); String[] suggestedNameOut = new String[FolderNameProvider.SUGGEST_MAX]; new FolderNameProvider().getSuggestedFolderName(mContext, list, suggestedNameOut); assertTrue(suggestedNameOut[0].equals("Work")); FolderNameInfo[] nameInfos = new FolderNameInfo[FolderNameProvider.SUGGEST_MAX]; new FolderNameProvider().getSuggestedFolderName(mContext, list, nameInfos); assertEquals("Work", nameInfos[0].getLabel()); suggestedNameOut[0] = "candidate1"; suggestedNameOut[1] = "candidate2"; suggestedNameOut[2] = "candidate3"; new FolderNameProvider().getSuggestedFolderName(mContext, list, suggestedNameOut); assertTrue(suggestedNameOut[3].equals("Work")); nameInfos[0] = new FolderNameInfo("candidate1", 0.9); nameInfos[1] = new FolderNameInfo("candidate2", 0.8); nameInfos[2] = new FolderNameInfo("candidate3", 0.7); new FolderNameProvider().getSuggestedFolderName(mContext, list, nameInfos); assertEquals("Work", nameInfos[3].getLabel()); } } src/com/android/launcher3/FolderInfo.java +2 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ public class FolderInfo extends ItemInfo { public static final int FLAG_MANUAL_FOLDER_NAME = 0x00000008; public static final String EXTRA_FOLDER_SUGGESTIONS = "suggest"; public int options; public Intent suggestedFolderNames; Loading src/com/android/launcher3/folder/Folder.java +46 −18 Original line number Diff line number Diff line Loading @@ -89,6 +89,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * Represents a set of icons chosen by the user or generated by the system. Loading Loading @@ -301,12 +303,12 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo post(() -> { if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { if (TextUtils.isEmpty(mFolderName.getText())) { String[] suggestedNames = mInfo.suggestedFolderNames.getStringArrayExtra("suggest"); mFolderName.setText(suggestedNames[0]); mFolderName.displayCompletions(Arrays.asList(suggestedNames).subList(1, suggestedNames.length)); mFolderName.setEnteredCompose(false); FolderNameInfo[] nameInfos = (FolderNameInfo[]) mInfo.suggestedFolderNames.getParcelableArrayExtra( FolderInfo.EXTRA_FOLDER_SUGGESTIONS); if (nameInfos != null) { showLabelSuggestion(nameInfos); } } } mFolderName.setHint(""); Loading Loading @@ -443,23 +445,49 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo } /** * Show suggested folder title. * Show suggested folder title in FolderEditText, push InputMethodManager suggestions and save * the suggestedFolderNames. */ public void showSuggestedTitle(String[] suggestName) { public void showSuggestedTitle(FolderNameInfo[] nameInfos) { if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { mInfo.suggestedFolderNames = new Intent().putExtra("suggest", suggestName); mInfo.suggestedFolderNames = new Intent().putExtra(FolderInfo.EXTRA_FOLDER_SUGGESTIONS, nameInfos); if (TextUtils.isEmpty(mFolderName.getText().toString()) && !mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) { if (suggestName.length > 0 && !TextUtils.isEmpty(suggestName[0])) { showLabelSuggestion(nameInfos); } } } /** * Show suggested folder title in FolderEditText if the first suggestion is non-empty, push * InputMethodManager suggestions. */ private void showLabelSuggestion(FolderNameInfo[] nameInfos) { if (nameInfos == 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 && !TextUtils.isEmpty( nameInfos[0].getLabel()) || nameInfos.length > 1 && nameInfos[1] != null && !TextUtils.isEmpty( nameInfos[1].getLabel()); CharSequence firstLabel = nameInfos[0].getLabel(); if (shouldOpen) { if (!TextUtils.isEmpty(firstLabel)) { mFolderName.setHint(""); mFolderName.setText(suggestName[0]); mInfo.title = suggestName[0]; mFolderName.setText(firstLabel); mInfo.title = firstLabel; } animateOpen(mInfo.contents, 0, true); mFolderName.showKeyboard(); mFolderName.displayCompletions( Arrays.asList(suggestName).subList(1, suggestName.length)); } } Arrays.asList(nameInfos).subList(1, nameInfos.length).stream() .filter(Objects::nonNull) .map(s -> s.getLabel().toString()) .collect(Collectors.toList())); } } Loading src/com/android/launcher3/folder/FolderIcon.java +7 −6 Original line number Diff line number Diff line Loading @@ -393,15 +393,16 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true); final int finalIndex = index; String[] suggestedNameOut = new String[FolderNameProvider.SUGGEST_MAX]; FolderNameInfo[] nameInfos = new FolderNameInfo[FolderNameProvider.SUGGEST_MAX]; if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { Executors.UI_HELPER_EXECUTOR.post(() -> { d.folderNameProvider.getSuggestedFolderName( getContext(), mInfo.contents, suggestedNameOut); showFinalView(finalIndex, item, suggestedNameOut); getContext(), mInfo.contents, nameInfos); showFinalView(finalIndex, item, nameInfos); }); } else { showFinalView(finalIndex, item, suggestedNameOut); showFinalView(finalIndex, item, nameInfos); } } else { addItem(item); Loading @@ -409,12 +410,12 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel } private void showFinalView(int finalIndex, final WorkspaceItemInfo item, String[] suggestedNameOut) { FolderNameInfo[] nameInfos) { postDelayed(() -> { mPreviewItemManager.hidePreviewItem(finalIndex, false); mFolder.showItem(item); invalidate(); mFolder.showSuggestedTitle(suggestedNameOut); mFolder.showSuggestedTitle(nameInfos); }, DROP_IN_ANIMATION_DURATION); } Loading src/com/android/launcher3/folder/FolderNameInfo.java 0 → 100644 +83 −0 Original line number Diff line number Diff line /* * 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; } /** * 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; } } Loading
robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java +10 −9 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ */ package com.android.launcher3.folder; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -61,15 +61,16 @@ public final class FolderNameProviderTest { ArrayList<WorkspaceItemInfo> list = new ArrayList<>(); list.add(mItem1); list.add(mItem2); String[] suggestedNameOut = new String[FolderNameProvider.SUGGEST_MAX]; new FolderNameProvider().getSuggestedFolderName(mContext, list, suggestedNameOut); assertTrue(suggestedNameOut[0].equals("Work")); FolderNameInfo[] nameInfos = new FolderNameInfo[FolderNameProvider.SUGGEST_MAX]; new FolderNameProvider().getSuggestedFolderName(mContext, list, nameInfos); assertEquals("Work", nameInfos[0].getLabel()); suggestedNameOut[0] = "candidate1"; suggestedNameOut[1] = "candidate2"; suggestedNameOut[2] = "candidate3"; new FolderNameProvider().getSuggestedFolderName(mContext, list, suggestedNameOut); assertTrue(suggestedNameOut[3].equals("Work")); nameInfos[0] = new FolderNameInfo("candidate1", 0.9); nameInfos[1] = new FolderNameInfo("candidate2", 0.8); nameInfos[2] = new FolderNameInfo("candidate3", 0.7); new FolderNameProvider().getSuggestedFolderName(mContext, list, nameInfos); assertEquals("Work", nameInfos[3].getLabel()); } }
src/com/android/launcher3/FolderInfo.java +2 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,8 @@ public class FolderInfo extends ItemInfo { public static final int FLAG_MANUAL_FOLDER_NAME = 0x00000008; public static final String EXTRA_FOLDER_SUGGESTIONS = "suggest"; public int options; public Intent suggestedFolderNames; Loading
src/com/android/launcher3/folder/Folder.java +46 −18 Original line number Diff line number Diff line Loading @@ -89,6 +89,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * Represents a set of icons chosen by the user or generated by the system. Loading Loading @@ -301,12 +303,12 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo post(() -> { if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { if (TextUtils.isEmpty(mFolderName.getText())) { String[] suggestedNames = mInfo.suggestedFolderNames.getStringArrayExtra("suggest"); mFolderName.setText(suggestedNames[0]); mFolderName.displayCompletions(Arrays.asList(suggestedNames).subList(1, suggestedNames.length)); mFolderName.setEnteredCompose(false); FolderNameInfo[] nameInfos = (FolderNameInfo[]) mInfo.suggestedFolderNames.getParcelableArrayExtra( FolderInfo.EXTRA_FOLDER_SUGGESTIONS); if (nameInfos != null) { showLabelSuggestion(nameInfos); } } } mFolderName.setHint(""); Loading Loading @@ -443,23 +445,49 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo } /** * Show suggested folder title. * Show suggested folder title in FolderEditText, push InputMethodManager suggestions and save * the suggestedFolderNames. */ public void showSuggestedTitle(String[] suggestName) { public void showSuggestedTitle(FolderNameInfo[] nameInfos) { if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { mInfo.suggestedFolderNames = new Intent().putExtra("suggest", suggestName); mInfo.suggestedFolderNames = new Intent().putExtra(FolderInfo.EXTRA_FOLDER_SUGGESTIONS, nameInfos); if (TextUtils.isEmpty(mFolderName.getText().toString()) && !mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) { if (suggestName.length > 0 && !TextUtils.isEmpty(suggestName[0])) { showLabelSuggestion(nameInfos); } } } /** * Show suggested folder title in FolderEditText if the first suggestion is non-empty, push * InputMethodManager suggestions. */ private void showLabelSuggestion(FolderNameInfo[] nameInfos) { if (nameInfos == 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 && !TextUtils.isEmpty( nameInfos[0].getLabel()) || nameInfos.length > 1 && nameInfos[1] != null && !TextUtils.isEmpty( nameInfos[1].getLabel()); CharSequence firstLabel = nameInfos[0].getLabel(); if (shouldOpen) { if (!TextUtils.isEmpty(firstLabel)) { mFolderName.setHint(""); mFolderName.setText(suggestName[0]); mInfo.title = suggestName[0]; mFolderName.setText(firstLabel); mInfo.title = firstLabel; } animateOpen(mInfo.contents, 0, true); mFolderName.showKeyboard(); mFolderName.displayCompletions( Arrays.asList(suggestName).subList(1, suggestName.length)); } } Arrays.asList(nameInfos).subList(1, nameInfos.length).stream() .filter(Objects::nonNull) .map(s -> s.getLabel().toString()) .collect(Collectors.toList())); } } Loading
src/com/android/launcher3/folder/FolderIcon.java +7 −6 Original line number Diff line number Diff line Loading @@ -393,15 +393,16 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true); final int finalIndex = index; String[] suggestedNameOut = new String[FolderNameProvider.SUGGEST_MAX]; FolderNameInfo[] nameInfos = new FolderNameInfo[FolderNameProvider.SUGGEST_MAX]; if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { Executors.UI_HELPER_EXECUTOR.post(() -> { d.folderNameProvider.getSuggestedFolderName( getContext(), mInfo.contents, suggestedNameOut); showFinalView(finalIndex, item, suggestedNameOut); getContext(), mInfo.contents, nameInfos); showFinalView(finalIndex, item, nameInfos); }); } else { showFinalView(finalIndex, item, suggestedNameOut); showFinalView(finalIndex, item, nameInfos); } } else { addItem(item); Loading @@ -409,12 +410,12 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel } private void showFinalView(int finalIndex, final WorkspaceItemInfo item, String[] suggestedNameOut) { FolderNameInfo[] nameInfos) { postDelayed(() -> { mPreviewItemManager.hidePreviewItem(finalIndex, false); mFolder.showItem(item); invalidate(); mFolder.showSuggestedTitle(suggestedNameOut); mFolder.showSuggestedTitle(nameInfos); }, DROP_IN_ANIMATION_DURATION); } Loading
src/com/android/launcher3/folder/FolderNameInfo.java 0 → 100644 +83 −0 Original line number Diff line number Diff line /* * 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; } /** * 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; } }