diff options
-rw-r--r-- | res/values-sw600dp/config.xml | 1 | ||||
-rw-r--r-- | src/com/android/launcher2/DeferredHandler.java | 12 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 44 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 19 |
4 files changed, 67 insertions, 9 deletions
diff --git a/res/values-sw600dp/config.xml b/res/values-sw600dp/config.xml index 02dd29057..b67b9c1c0 100644 --- a/res/values-sw600dp/config.xml +++ b/res/values-sw600dp/config.xml @@ -5,7 +5,6 @@ <integer name="cell_count_y">6</integer> <integer name="hotseat_cell_count">7</integer> <integer name="hotseat_all_apps_index">3</integer> - <!-- DragController --> <integer name="config_flingToDeleteMinVelocity">-1000</integer> diff --git a/src/com/android/launcher2/DeferredHandler.java b/src/com/android/launcher2/DeferredHandler.java index 930da56aa..b7e48b130 100644 --- a/src/com/android/launcher2/DeferredHandler.java +++ b/src/com/android/launcher2/DeferredHandler.java @@ -98,6 +98,18 @@ public class DeferredHandler { } } + /** Runs all queued Runnables from the calling thread. */ + public void flush() { + LinkedList<Runnable> queue = new LinkedList<Runnable>(); + synchronized (mQueue) { + queue.addAll(mQueue); + mQueue.clear(); + } + for (Runnable r : queue) { + r.run(); + } + } + void scheduleNextLocked() { if (mQueue.size() > 0) { Runnable peek = mQueue.getFirst(); diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 98d4c094d..70c641b92 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -181,7 +181,7 @@ public final class Launcher extends Activity "com.android.launcher.toolbar_voice_search_icon"; /** The different states that Launcher can be in. */ - private enum State { WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED }; + private enum State { NONE, WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED }; private State mState = State.WORKSPACE; private AnimatorSet mStateAnimation; private AnimatorSet mDividerAnimator; @@ -229,6 +229,10 @@ public final class Launcher extends Activity private boolean mAutoAdvanceRunning = false; private Bundle mSavedState; + // We set the state in both onCreate and then onNewIntent in some cases, which causes both + // scroll issues (because the workspace may not have been measured yet) and extra work. + // Instead, just save the state that we need to restore Launcher to, and commit it in onResume. + private State mOnResumeState = State.NONE; private SpannableStringBuilder mDefaultKeySsb = null; @@ -239,6 +243,9 @@ public final class Launcher extends Activity private boolean mWaitingForResult; private boolean mOnResumeNeedsLoad; + // Keep track of whether the user has left launcher + private static boolean sPausedFromUserAction = false; + private Bundle mSavedInstanceState; private LauncherModel mModel; @@ -370,7 +377,15 @@ public final class Launcher extends Activity } if (!mRestoring) { - mModel.startLoader(true, mWorkspace.getCurrentPage()); + if (sPausedFromUserAction) { + // If the user leaves launcher, then we should just load items asynchronously when + // they return. + mModel.startLoader(true, -1); + } else { + // We only load the page synchronously if the user rotates (or triggers a + // configuration change) while launcher is in the foreground + mModel.startLoader(true, mWorkspace.getCurrentPage()); + } } if (!mModel.isAllAppsLoaded()) { @@ -391,6 +406,11 @@ public final class Launcher extends Activity unlockScreenOrientation(true); } + protected void onUserLeaveHint() { + super.onUserLeaveHint(); + sPausedFromUserAction = true; + } + private void updateGlobalIcons() { boolean searchVisible = false; boolean voiceVisible = false; @@ -676,10 +696,19 @@ public final class Launcher extends Activity protected void onResume() { super.onResume(); + // Restore the previous launcher state + if (mOnResumeState == State.WORKSPACE) { + showWorkspace(false); + } else if (mOnResumeState == State.APPS_CUSTOMIZE) { + showAllApps(false); + } + mOnResumeState = State.NONE; + // Process any items that were added while Launcher was away InstallShortcutReceiver.flushInstallQueue(this); mPaused = false; + sPausedFromUserAction = false; if (mRestoring || mOnResumeNeedsLoad) { mWorkspaceLoading = true; mModel.startLoader(true, -1); @@ -823,7 +852,7 @@ public final class Launcher extends Activity State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal())); if (state == State.APPS_CUSTOMIZE) { - showAllApps(false); + mOnResumeState = State.APPS_CUSTOMIZE; } int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1); @@ -1360,7 +1389,14 @@ public final class Launcher extends Activity closeFolder(); exitSpringLoadedDragMode(); - showWorkspace(alreadyOnHome); + + // If we are already on home, then just animate back to the workspace, otherwise, just + // wait until onResume to set the state back to Workspace + if (alreadyOnHome) { + showWorkspace(true); + } else { + mOnResumeState = State.WORKSPACE; + } final View v = getWindow().peekDecorView(); if (v != null && v.getWindowToken() != null) { diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 29723d447..ab29fc688 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -918,6 +918,11 @@ public class LauncherModel extends BroadcastReceiver { // data structures, we can't allow any other thread to touch that data, but because // this call is synchronous, we can get away with not locking). + // The LauncherModel is static in the LauncherApplication and mHandler may have queued + // operations from the previous activity. We need to ensure that all queued operations + // are executed before any synchronous binding work is done. + mHandler.flush(); + // Divide the set of loaded items into those that we are binding synchronously, and // everything else that is to be bound normally (asynchronously). bindWorkspace(synchronousBindPage); @@ -1557,7 +1562,8 @@ public class LauncherModel extends BroadcastReceiver { return; } - final int currentScreen = (synchronizeBindPage > -1) ? synchronizeBindPage : + final boolean isLoadingSynchronously = (synchronizeBindPage > -1); + final int currentScreen = isLoadingSynchronously ? synchronizeBindPage : oldCallbacks.getCurrentWorkspaceScreen(); // Load all the items that are on the current page first (and in the process, unbind @@ -1609,10 +1615,11 @@ public class LauncherModel extends BroadcastReceiver { bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, currentFolders, null); - // Load all the remaining pages + // Load all the remaining pages (if we are loading synchronously, we want to defer this + // work until after the first render) mDeferredBindRunnables.clear(); bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders, - mDeferredBindRunnables); + (isLoadingSynchronously ? mDeferredBindRunnables : null)); // Tell the workspace that we're done binding items r = new Runnable() { @@ -1631,7 +1638,11 @@ public class LauncherModel extends BroadcastReceiver { mIsLoadingAndBindingWorkspace = false; } }; - mDeferredBindRunnables.add(r); + if (isLoadingSynchronously) { + mDeferredBindRunnables.add(r); + } else { + runOnMainThread(r); + } } private void loadAndBindAllApps() { |