Preserving the open folder state across rotation
Bug: 24900496
Change-Id: Ie1318b82b497957b99603b11ec338dd50d51b962
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index ee9e4f2..d825071 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -612,8 +612,30 @@
mDragController.forceTouchMove();
}
- FolderPagedView pages = (FolderPagedView) mContent;
- pages.verifyVisibleHighResIcons(pages.getNextPage());
+ mContent.verifyVisibleHighResIcons(mContent.getNextPage());
+ }
+
+ /**
+ * Opens the folder without any animation
+ */
+ public void open() {
+ if (!(getParent() instanceof DragLayer)) return;
+
+ mContent.completePendingPageChanges();
+ if (!mDragInProgress) {
+ // Open on the first page.
+ mContent.snapToPageImmediately(0);
+ }
+ centerAboutIcon();
+ mFolderName.setTranslationX(0);
+ mContent.setMarkerScale(1);
+
+ // Make sure the folder picks up the last drag move even if the finger doesn't move.
+ if (mDragController.isDragging()) {
+ mDragController.forceTouchMove();
+ }
+
+ mContent.verifyVisibleHighResIcons(mContent.getNextPage());
}
public void beginExternalDrag(ShortcutInfo item) {
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 7d1cb75..26b9693 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -373,7 +373,7 @@
item = (ShortcutInfo) mDragInfo;
}
mFolder.beginExternalDrag(item);
- mLauncher.openFolder(FolderIcon.this);
+ mLauncher.openFolder(FolderIcon.this, true);
}
};
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4a0c808..6654e9b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -115,10 +115,7 @@
import com.android.launcher3.widget.WidgetHostViewLoader;
import com.android.launcher3.widget.WidgetsContainerView;
-import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.util.ArrayList;
@@ -178,6 +175,8 @@
private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
// Type: int
private static final String RUNTIME_STATE = "launcher.state";
+ // Type: long
+ private static final String RUNTIME_STATE_OPEN_FOLDER_ID = "launcher.open_folder_id";
// Type: Content Values / parcelable
private static final String RUNTIME_STATE_PENDING_ADD_ITEM = "launcher.add_item";
// Type: parcelable
@@ -537,7 +536,7 @@
return;
}
// The underlying workspace and hotseat are temporarily suppressed by the search
- // overlay. So they sholudn't be accessible.
+ // overlay. So they shouldn't be accessible.
if (mWorkspace != null) {
mWorkspaceImportanceForAccessibility =
mWorkspace.getImportantForAccessibility();
@@ -1950,9 +1949,10 @@
super.onSaveInstanceState(outState);
outState.putInt(RUNTIME_STATE, mState.ordinal());
- // We close any open folder since it will not be re-opened, and we need to make sure
- // this state is reflected.
- closeFolder(false);
+ Folder openFolder = mWorkspace.getOpenFolder();
+ if (openFolder != null) {
+ outState.putLong(RUNTIME_STATE_OPEN_FOLDER_ID, openFolder.mInfo.id);
+ }
if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screenId > -1 &&
mWaitingForResult) {
@@ -2721,38 +2721,10 @@
throw new IllegalArgumentException("Input must be a FolderIcon");
}
- // TODO(sunnygoyal): Re-evaluate this code.
FolderIcon folderIcon = (FolderIcon) v;
- final FolderInfo info = folderIcon.getFolderInfo();
- Folder openFolder = mWorkspace.getFolderForTag(info);
-
- // If the folder info reports that the associated folder is open, then verify that
- // it is actually opened. There have been a few instances where this gets out of sync.
- if (info.opened && openFolder == null) {
- Log.d(TAG, "Folder info marked as open, but associated folder is not open. Screen: "
- + info.screenId + " (" + info.cellX + ", " + info.cellY + ")");
- info.opened = false;
- }
-
- if (!info.opened && !folderIcon.getFolder().isDestroyed()) {
- // Close any open folder
- closeFolder();
+ if (!folderIcon.getFolderInfo().opened && !folderIcon.getFolder().isDestroyed()) {
// Open the requested folder
- openFolder(folderIcon);
- } else {
- // Find the open folder...
- int folderScreen;
- if (openFolder != null) {
- folderScreen = mWorkspace.getPageForView(openFolder);
- // .. and close it
- closeFolder(openFolder, true);
- if (folderScreen != mWorkspace.getCurrentPage()) {
- // Close any folder open on the current screen
- closeFolder();
- // Pull the folder onto this screen
- openFolder(folderIcon);
- }
- }
+ openFolder(folderIcon, true);
}
if (mLauncherCallbacks != null) {
@@ -3059,7 +3031,7 @@
}
}
- private void growAndFadeOutFolderIcon(FolderIcon fi) {
+ private void growAndFadeOutFolderIcon(FolderIcon fi, boolean animate) {
if (fi == null) return;
FolderInfo info = (FolderInfo) fi.getTag();
if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
@@ -3079,8 +3051,7 @@
}
oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));
oa.start();
- if (Utilities.isPowerSaverOn(this)) {
- // Animations are disabled in battery saver mode, so just skip to the end state.
+ if (!animate) {
oa.end();
}
}
@@ -3116,9 +3087,11 @@
* is animated relative to the specified View. If the View is null, no animation
* is played.
*
- * @param folderInfo The FolderInfo describing the folder to open.
+ * @param folderIcon The FolderIcon describing the folder to open.
*/
- public void openFolder(FolderIcon folderIcon) {
+ public void openFolder(FolderIcon folderIcon, boolean animate) {
+ animate &= !Utilities.isPowerSaverOn(this);
+
Folder folder = folderIcon.getFolder();
Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;
if (openFolder != null && openFolder != folder) {
@@ -3137,13 +3110,17 @@
// There was a one-off crash where the folder had a parent already.
if (folder.getParent() == null) {
mDragLayer.addView(folder);
- mDragController.addDropTarget((DropTarget) folder);
+ mDragController.addDropTarget(folder);
} else {
Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +
folder.getParent() + ").");
}
- folder.animateOpen();
- growAndFadeOutFolderIcon(folderIcon);
+ if (animate) {
+ folder.animateOpen();
+ } else {
+ folder.open();
+ }
+ growAndFadeOutFolderIcon(folderIcon, animate);
// Notify the accessibility manager that this folder "window" has appeared and occluded
// the workspace items
@@ -3166,6 +3143,8 @@
}
public void closeFolder(Folder folder, boolean animate) {
+ animate &= !Utilities.isPowerSaverOn(this);
+
folder.getInfo().opened = false;
ViewGroup parent = (ViewGroup) folder.getParent().getParent();
@@ -4154,6 +4133,26 @@
if (!mWorkspace.hasFocus()) {
mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();
}
+
+ long folderId = mSavedState.getLong(RUNTIME_STATE_OPEN_FOLDER_ID);
+ if (folderId != 0) {
+ View view = mWorkspace.getHomescreenIconByItemId(folderId);
+ if (view instanceof FolderIcon) {
+ FolderIcon icon = (FolderIcon) view;
+ FolderInfo info = icon.getFolderInfo();
+ long currentScreenId = mWorkspace.getScreenIdForPageIndex(
+ mWorkspace.getNextPage());
+ if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
+ || info.screenId == currentScreenId) {
+ // We can show the folder
+ openFolder(icon, false);
+ } else {
+ Launcher.addDumpLog(TAG, "Saved state contains folder " + info +
+ " but current screen is " + currentScreenId);
+ }
+ }
+ }
+
mSavedState = null;
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 869d42c..d0f15c6 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -2092,20 +2092,6 @@
if (getNextPage() < getChildCount() -1) snapToPage(getNextPage() + 1);
}
- public int getPageForView(View v) {
- int result = -1;
- if (v != null) {
- ViewParent vp = v.getParent();
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- if (vp == getPageAt(i)) {
- return i;
- }
- }
- }
- return result;
- }
-
@Override
public boolean performLongClick() {
mCancelTap = true;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index e86758a..d66984c 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3727,8 +3727,7 @@
* the hotseat and workspace pages
*/
ArrayList<ShortcutAndWidgetContainer> getAllShortcutAndWidgetContainers() {
- ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
- new ArrayList<ShortcutAndWidgetContainer>();
+ ArrayList<ShortcutAndWidgetContainer> childrenLayouts = new ArrayList<>();
int screenCount = getChildCount();
for (int screen = 0; screen < screenCount; screen++) {
childrenLayouts.add(((CellLayout) getChildAt(screen)).getShortcutsAndWidgets());
@@ -3739,17 +3738,6 @@
return childrenLayouts;
}
- public Folder getFolderForTag(final Object tag) {
- return (Folder) getFirstMatch(new ItemOperator() {
-
- @Override
- public boolean evaluate(ItemInfo info, View v, View parent) {
- return (v instanceof Folder) && (((Folder) v).getInfo() == tag)
- && ((Folder) v).getInfo().opened;
- }
- });
- }
-
public View getHomescreenIconByItemId(final long id) {
return getFirstMatch(new ItemOperator() {