diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index be1d0b68fd..7128603c1a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -987,15 +987,20 @@ public class TaskbarActivityContext extends BaseTaskbarContext { FolderIcon folderIcon = (FolderIcon) view; Folder folder = folderIcon.getFolder(); - folder.setOnFolderStateChangedListener(newState -> { - if (newState == Folder.STATE_OPEN) { - setTaskbarWindowFocusableForIme(true); - } else if (newState == Folder.STATE_CLOSED) { - // Defer by a frame to ensure we're no longer fullscreen and thus won't jump. - getDragLayer().post(() -> setTaskbarWindowFocusableForIme(false)); - folder.setOnFolderStateChangedListener(null); - } - }); + folder.setPriorityOnFolderStateChangedListener( + new Folder.OnFolderStateChangedListener() { + @Override + public void onFolderStateChanged(int newState) { + if (newState == Folder.STATE_OPEN) { + setTaskbarWindowFocusableForIme(true); + } else if (newState == Folder.STATE_CLOSED) { + // Defer by a frame to ensure we're no longer fullscreen and thus + // won't jump. + getDragLayer().post(() -> setTaskbarWindowFocusableForIme(false)); + folder.setPriorityOnFolderStateChangedListener(null); + } + } + }); setTaskbarWindowFullscreen(true); @@ -1055,7 +1060,21 @@ public class TaskbarActivityContext extends BaseTaskbarContext { Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e); return; } + } + // If the app was launched from a folder, stash the taskbar after it closes + Folder f = Folder.getOpen(this); + if (f != null && f.getInfo().id == info.container) { + f.addOnFolderStateChangedListener(new Folder.OnFolderStateChangedListener() { + @Override + public void onFolderStateChanged(int newState) { + if (newState == Folder.STATE_CLOSED) { + f.removeOnFolderStateChangedListener(this); + mControllers.taskbarStashController + .updateAndAnimateTransientTaskbar(true); + } + } + }); } mControllers.uiController.onTaskbarIconLaunched(info); mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 8bf7ec234e..76e74c0727 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -210,7 +210,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo @ViewDebug.IntToString(from = STATE_OPEN, to = "STATE_OPEN"), }) private int mState = STATE_CLOSED; - private OnFolderStateChangedListener mOnFolderStateChangedListener; + private final List mOnFolderStateChangedListeners = + new ArrayList<>(); + private OnFolderStateChangedListener mPriorityOnFolderStateChangedListener; @ViewDebug.ExportedProperty(category = "launcher") private boolean mRearrangeOnClose = false; boolean mItemsInvalidated = false; @@ -1665,18 +1667,43 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo return windowBottomPx - folderBottomPx; } + /** + * Save this listener for the special case of when we update the state and concurrently + * add another listener to {@link #mOnFolderStateChangedListeners} to avoid a + * ConcurrentModificationException + */ + public void setPriorityOnFolderStateChangedListener(OnFolderStateChangedListener listener) { + mPriorityOnFolderStateChangedListener = listener; + } + private void setState(@FolderState int newState) { mState = newState; - if (mOnFolderStateChangedListener != null) { - mOnFolderStateChangedListener.onFolderStateChanged(mState); + if (mPriorityOnFolderStateChangedListener != null) { + mPriorityOnFolderStateChangedListener.onFolderStateChanged(mState); + } + for (OnFolderStateChangedListener listener : mOnFolderStateChangedListeners) { + if (listener != null) { + listener.onFolderStateChanged(mState); + } } } - public void setOnFolderStateChangedListener(@Nullable OnFolderStateChangedListener listener) { - mOnFolderStateChangedListener = listener; + /** + * Adds the provided listener to the running list of Folder listeners + * {@link #mOnFolderStateChangedListeners} + */ + public void addOnFolderStateChangedListener(@Nullable OnFolderStateChangedListener listener) { + if (listener != null) { + mOnFolderStateChangedListeners.add(listener); + } } - /** Listener that can be registered via {@link Folder#setOnFolderStateChangedListener} */ + /** Removes the provided listener from the running list of Folder listeners */ + public void removeOnFolderStateChangedListener(OnFolderStateChangedListener listener) { + mOnFolderStateChangedListeners.remove(listener); + } + + /** Listener that can be registered via {@link #addOnFolderStateChangedListener} */ public interface OnFolderStateChangedListener { /** See {@link Folder.FolderState} */ void onFolderStateChanged(@FolderState int newState);