Loading src/com/android/launcher3/Launcher.java +5 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.folder.FolderGridOrganizer; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.folder.FolderNameProvider; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.icons.IconCache; import com.android.launcher3.keyboard.CustomActionsPopup; Loading Loading @@ -553,6 +554,10 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mStateManager; } public FolderNameProvider getFolderNameProvider() { return new FolderNameProvider(); } @Override public <T extends View> T findViewById(int id) { return mLauncherView.findViewById(id); Loading src/com/android/launcher3/config/BaseFlags.java +4 −1 Original line number Diff line number Diff line Loading @@ -108,6 +108,10 @@ public abstract class BaseFlags { "FAKE_LANDSCAPE_UI", false, "Rotate launcher UI instead of using transposed layout"); public static final TogglableFlag FOLDER_NAME_SUGGEST = new TogglableFlag( "FOLDER_NAME_SUGGEST", true, "Suggests folder names instead of blank text."); public static final TogglableFlag APP_SEARCH_IMPROVEMENTS = new TogglableFlag( "APP_SEARCH_IMPROVEMENTS", false, "Adds localized title and keyword search and ranking"); Loading @@ -119,7 +123,6 @@ public abstract class BaseFlags { "ASSISTANT_GIVES_LAUNCHER_FOCUS", false, "Allow Launcher to handle nav bar gestures while Assistant is running over it"); public static void initialize(Context context) { // Avoid the disk read for user builds if (Utilities.IS_DEBUG_DEVICE) { Loading src/com/android/launcher3/folder/Folder.java +16 −5 Original line number Diff line number Diff line Loading @@ -401,7 +401,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName.setText(""); mFolderName.setHint(R.string.folder_hint_text); } // In case any children didn't come across during loading, clean up the folder accordingly mFolderIcon.post(() -> { if (getItemCount() <= 1) { Loading @@ -410,6 +409,22 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo }); } /** * Show suggested folder title. */ public void showSuggestedTitle(CharSequence suggestName) { if (FeatureFlags.FOLDER_NAME_SUGGEST.get() && mInfo.contents.size() == 2) { if (!TextUtils.isEmpty(suggestName)) { mFolderName.setHint(suggestName); mFolderName.setText(suggestName); mFolderName.showKeyboard(); mInfo.title = suggestName; } animateOpen(); } } /** * Creates a new UserFolder, inflated from R.layout.user_folder. * Loading Loading @@ -532,8 +547,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice. mDeleteFolderOnDropCompleted = false; centerAboutIcon(); AnimatorSet anim = new FolderAnimationManager(this, true /* isOpening */).getAnimator(); anim.addListener(new AnimatorListenerAdapter() { @Override Loading Loading @@ -592,7 +605,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo if (mDragController.isDragging()) { mDragController.forceTouchMove(); } mContent.verifyVisibleHighResIcons(mContent.getNextPage()); } Loading Loading @@ -877,7 +889,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo // Reordering may have occured, and we need to save the new item locations. We do this once // at the end to prevent unnecessary database operations. updateItemLocationsInDatabaseBatch(); // Use the item count to check for multi-page as the folder UI may not have // been refreshed yet. if (getItemCount() <= mContent.itemsPerPage()) { Loading src/com/android/launcher3/folder/FolderIcon.java +13 −6 Original line number Diff line number Diff line Loading @@ -58,12 +58,14 @@ import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dot.FolderDotInfo; import com.android.launcher3.dragndrop.BaseItemDragListener; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.util.Executors; import com.android.launcher3.util.Thunk; import com.android.launcher3.views.IconLabelDotView; import com.android.launcher3.widget.PendingAddShortcutInfo; Loading Loading @@ -368,12 +370,17 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true); final int finalIndex = index; postDelayed(new Runnable() { public void run() { String[] suggestedNameOut = new String[1]; if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { Executors.UI_HELPER_EXECUTOR.post(() -> mLauncher.getFolderNameProvider() .getSuggestedFolderName(getContext(), mInfo.contents, suggestedNameOut)); } postDelayed(() -> { mPreviewItemManager.hidePreviewItem(finalIndex, false); mFolder.showItem(item); invalidate(); } mFolder.showSuggestedTitle(suggestedNameOut[0]); }, DROP_IN_ANIMATION_DURATION); } else { addItem(item); Loading src/com/android/launcher3/folder/FolderNameProvider.java 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.content.ComponentName; import android.content.Context; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.WorkspaceItemInfo; import java.util.ArrayList; /** * Locates provider for the folder name. */ public class FolderNameProvider { /** * Returns suggested folder name. */ public CharSequence getSuggestedFolderName(Context context, ArrayList<WorkspaceItemInfo> workspaceItemInfos, CharSequence[] suggestName) { // Currently only run the algorithm on initial folder creation. // For more than 2 items in the folder, the ranking algorithm for finding // candidate folder name should be rewritten. if (workspaceItemInfos.size() == 2) { ComponentName cmp1 = workspaceItemInfos.get(0).getTargetComponent(); ComponentName cmp2 = workspaceItemInfos.get(1).getTargetComponent(); String pkgName0 = cmp1 == null ? "" : cmp1.getPackageName(); String pkgName1 = cmp2 == null ? "" : cmp2.getPackageName(); // If the two icons are from the same package, // then assign the main icon's name if (pkgName0.equals(pkgName1)) { WorkspaceItemInfo wInfo0 = workspaceItemInfos.get(0); WorkspaceItemInfo wInfo1 = workspaceItemInfos.get(1); if (workspaceItemInfos.get(0).itemType == Favorites.ITEM_TYPE_APPLICATION) { suggestName[0] = wInfo0.title; } else if (wInfo1.itemType == Favorites.ITEM_TYPE_APPLICATION) { suggestName[0] = wInfo1.title; } return suggestName[0]; // two icons are all shortcuts. Don't assign title } } return suggestName[0]; } } Loading
src/com/android/launcher3/Launcher.java +5 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.folder.FolderGridOrganizer; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.folder.FolderNameProvider; import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.icons.IconCache; import com.android.launcher3.keyboard.CustomActionsPopup; Loading Loading @@ -553,6 +554,10 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mStateManager; } public FolderNameProvider getFolderNameProvider() { return new FolderNameProvider(); } @Override public <T extends View> T findViewById(int id) { return mLauncherView.findViewById(id); Loading
src/com/android/launcher3/config/BaseFlags.java +4 −1 Original line number Diff line number Diff line Loading @@ -108,6 +108,10 @@ public abstract class BaseFlags { "FAKE_LANDSCAPE_UI", false, "Rotate launcher UI instead of using transposed layout"); public static final TogglableFlag FOLDER_NAME_SUGGEST = new TogglableFlag( "FOLDER_NAME_SUGGEST", true, "Suggests folder names instead of blank text."); public static final TogglableFlag APP_SEARCH_IMPROVEMENTS = new TogglableFlag( "APP_SEARCH_IMPROVEMENTS", false, "Adds localized title and keyword search and ranking"); Loading @@ -119,7 +123,6 @@ public abstract class BaseFlags { "ASSISTANT_GIVES_LAUNCHER_FOCUS", false, "Allow Launcher to handle nav bar gestures while Assistant is running over it"); public static void initialize(Context context) { // Avoid the disk read for user builds if (Utilities.IS_DEBUG_DEVICE) { Loading
src/com/android/launcher3/folder/Folder.java +16 −5 Original line number Diff line number Diff line Loading @@ -401,7 +401,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName.setText(""); mFolderName.setHint(R.string.folder_hint_text); } // In case any children didn't come across during loading, clean up the folder accordingly mFolderIcon.post(() -> { if (getItemCount() <= 1) { Loading @@ -410,6 +409,22 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo }); } /** * Show suggested folder title. */ public void showSuggestedTitle(CharSequence suggestName) { if (FeatureFlags.FOLDER_NAME_SUGGEST.get() && mInfo.contents.size() == 2) { if (!TextUtils.isEmpty(suggestName)) { mFolderName.setHint(suggestName); mFolderName.setText(suggestName); mFolderName.showKeyboard(); mInfo.title = suggestName; } animateOpen(); } } /** * Creates a new UserFolder, inflated from R.layout.user_folder. * Loading Loading @@ -532,8 +547,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice. mDeleteFolderOnDropCompleted = false; centerAboutIcon(); AnimatorSet anim = new FolderAnimationManager(this, true /* isOpening */).getAnimator(); anim.addListener(new AnimatorListenerAdapter() { @Override Loading Loading @@ -592,7 +605,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo if (mDragController.isDragging()) { mDragController.forceTouchMove(); } mContent.verifyVisibleHighResIcons(mContent.getNextPage()); } Loading Loading @@ -877,7 +889,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo // Reordering may have occured, and we need to save the new item locations. We do this once // at the end to prevent unnecessary database operations. updateItemLocationsInDatabaseBatch(); // Use the item count to check for multi-page as the folder UI may not have // been refreshed yet. if (getItemCount() <= mContent.itemsPerPage()) { Loading
src/com/android/launcher3/folder/FolderIcon.java +13 −6 Original line number Diff line number Diff line Loading @@ -58,12 +58,14 @@ import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dot.FolderDotInfo; import com.android.launcher3.dragndrop.BaseItemDragListener; import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.util.Executors; import com.android.launcher3.util.Thunk; import com.android.launcher3.views.IconLabelDotView; import com.android.launcher3.widget.PendingAddShortcutInfo; Loading Loading @@ -368,12 +370,17 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true); final int finalIndex = index; postDelayed(new Runnable() { public void run() { String[] suggestedNameOut = new String[1]; if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { Executors.UI_HELPER_EXECUTOR.post(() -> mLauncher.getFolderNameProvider() .getSuggestedFolderName(getContext(), mInfo.contents, suggestedNameOut)); } postDelayed(() -> { mPreviewItemManager.hidePreviewItem(finalIndex, false); mFolder.showItem(item); invalidate(); } mFolder.showSuggestedTitle(suggestedNameOut[0]); }, DROP_IN_ANIMATION_DURATION); } else { addItem(item); Loading
src/com/android/launcher3/folder/FolderNameProvider.java 0 → 100644 +61 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.content.ComponentName; import android.content.Context; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.WorkspaceItemInfo; import java.util.ArrayList; /** * Locates provider for the folder name. */ public class FolderNameProvider { /** * Returns suggested folder name. */ public CharSequence getSuggestedFolderName(Context context, ArrayList<WorkspaceItemInfo> workspaceItemInfos, CharSequence[] suggestName) { // Currently only run the algorithm on initial folder creation. // For more than 2 items in the folder, the ranking algorithm for finding // candidate folder name should be rewritten. if (workspaceItemInfos.size() == 2) { ComponentName cmp1 = workspaceItemInfos.get(0).getTargetComponent(); ComponentName cmp2 = workspaceItemInfos.get(1).getTargetComponent(); String pkgName0 = cmp1 == null ? "" : cmp1.getPackageName(); String pkgName1 = cmp2 == null ? "" : cmp2.getPackageName(); // If the two icons are from the same package, // then assign the main icon's name if (pkgName0.equals(pkgName1)) { WorkspaceItemInfo wInfo0 = workspaceItemInfos.get(0); WorkspaceItemInfo wInfo1 = workspaceItemInfos.get(1); if (workspaceItemInfos.get(0).itemType == Favorites.ITEM_TYPE_APPLICATION) { suggestName[0] = wInfo0.title; } else if (wInfo1.itemType == Favorites.ITEM_TYPE_APPLICATION) { suggestName[0] = wInfo1.title; } return suggestName[0]; // two icons are all shortcuts. Don't assign title } } return suggestName[0]; } }