summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/values-sw600dp/config.xml1
-rw-r--r--src/com/android/launcher2/DeferredHandler.java12
-rw-r--r--src/com/android/launcher2/Launcher.java44
-rw-r--r--src/com/android/launcher2/LauncherModel.java19
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() {