From d479e9ec2ee93137469ced269fc0e343a4f6be73 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 23 May 2012 15:14:34 -0700 Subject: Fixing issue with resource ids. (Bug 6532243) Change-Id: Ie4a245a224038a750e60b0203003638fd561713d --- res/values/attrs.xml | 6 ++++++ res/values/strings.xml | 12 ++++++++++++ res/values/styles.xml | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 224daac53..c76a6a5c4 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -157,4 +157,10 @@ + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 1416d40e9..4aee339e4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -260,4 +260,16 @@ s --> Folder: %1$s + + + + + + + + + + + + diff --git a/res/values/styles.xml b/res/values/styles.xml index 3d935a164..08c98c9f2 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -186,4 +186,10 @@ 0.0 2.0 + + + + -- cgit v1.2.3 From 36e6c5bb232f3a876753b91fb9ec604cda8664a5 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 19 Jul 2012 14:53:05 -0700 Subject: Disabling synchronous binding when returning home from another app while orientation has changed. (Bug 6792288) - Fixing issue where we were reverting to the first page of the workspace after launching an application from all apps, rotating, and returning home - Enabling rotation in master. Change-Id: I291b9d76b20244e9028b6f62164430bc3606644c --- res/values-sw600dp/config.xml | 1 - src/com/android/launcher2/Launcher.java | 44 +++++++++++++++++++++++++--- src/com/android/launcher2/LauncherModel.java | 14 ++++++--- 3 files changed, 50 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 @@ 6 7 3 - -1000 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..d4b7f7652 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -1557,7 +1557,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 +1610,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 +1633,11 @@ public class LauncherModel extends BroadcastReceiver { mIsLoadingAndBindingWorkspace = false; } }; - mDeferredBindRunnables.add(r); + if (isLoadingSynchronously) { + mDeferredBindRunnables.add(r); + } else { + runOnMainThread(r); + } } private void loadAndBindAllApps() { -- cgit v1.2.3 From a13a2f2a7bd0550d1ad973f760ff25e1a4137c43 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Mon, 23 Jul 2012 14:29:15 -0700 Subject: Fixing issue where defered unbind was running after synchronous bind. (Bug 6858398, Bug 6863181) Change-Id: I03dc3ae18528901cc88c79638a8495c1ab8d61af --- src/com/android/launcher2/DeferredHandler.java | 12 ++++++++++++ src/com/android/launcher2/LauncherModel.java | 5 +++++ 2 files changed, 17 insertions(+) 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 queue = new LinkedList(); + 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/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index d4b7f7652..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); -- cgit v1.2.3 From 1462de39f01cec0ba785386532719cb0207dd827 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Tue, 24 Jul 2012 22:34:36 -0700 Subject: Ensuring that restoreInstanceState is being called promptly for synchronously bound page Change-Id: I0e71c29f553ad360ec42a6a0b2529d16cbddd437 --- src/com/android/launcher2/CellLayout.java | 8 +++++++- src/com/android/launcher2/Launcher.java | 19 +++++++++++------- src/com/android/launcher2/LauncherModel.java | 12 +++++++++++ src/com/android/launcher2/Workspace.java | 30 ++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index c028ff1dc..97d9bc1b5 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -17,9 +17,9 @@ package com.android.launcher2; import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.animation.AnimatorListenerAdapter; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; @@ -37,8 +37,10 @@ import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; +import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; +import android.util.SparseArray; import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; @@ -532,6 +534,10 @@ public class CellLayout extends ViewGroup { return false; } + public void restoreInstanceState(SparseArray states) { + dispatchRestoreInstanceState(states); + } + @Override public void cancelLongPress() { super.cancelLongPress(); diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 70c641b92..ae2ca3b47 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -278,6 +278,8 @@ public final class Launcher extends Activity private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2]; private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2]; + private final ArrayList mSynchronouslyBoundPages = new ArrayList(); + static final ArrayList sDumpLogs = new ArrayList(); // We only want to get the SharedPreferences once since it does an FS stat each time we get @@ -1413,9 +1415,11 @@ public final class Launcher extends Activity } @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - // Do not call super here - mSavedInstanceState = savedInstanceState; + public void onRestoreInstanceState(Bundle state) { + super.onRestoreInstanceState(state); + for (int page: mSynchronouslyBoundPages) { + mWorkspace.restoreInstanceStateForChild(page); + } } @Override @@ -3314,6 +3318,10 @@ public final class Launcher extends Activity } } + public void onPageBoundSynchronously(int page) { + mSynchronouslyBoundPages.add(page); + } + /** * Callback saying that there aren't any more items to bind. * @@ -3329,10 +3337,7 @@ public final class Launcher extends Activity mSavedState = null; } - if (mSavedInstanceState != null) { - super.onRestoreInstanceState(mSavedInstanceState); - mSavedInstanceState = null; - } + mWorkspace.restoreInstanceStateForRemainingPages(); // If we received the result of any pending adds while the loader was running (e.g. the // widget configuration forced an orientation change), process them now. diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index ab29fc688..40a9e21dc 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -156,6 +156,7 @@ public class LauncherModel extends BroadcastReceiver { public boolean isAllAppsVisible(); public boolean isAllAppsButtonRank(int rank); public void bindSearchablesChanged(); + public void onPageBoundSynchronously(int page); } LauncherModel(LauncherApplication app, IconCache iconCache) { @@ -1614,6 +1615,17 @@ public class LauncherModel extends BroadcastReceiver { // Load items on the current page bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, currentFolders, null); + if (isLoadingSynchronously) { + r = new Runnable() { + public void run() { + Callbacks callbacks = tryGetCallbacks(oldCallbacks); + if (callbacks != null) { + callbacks.onPageBoundSynchronously(currentScreen); + } + } + }; + runOnMainThread(r); + } // Load all the remaining pages (if we are loading synchronously, we want to defer this // work until after the first render) diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 331e86f33..44b9f68da 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -47,6 +47,7 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; +import android.util.SparseArray; import android.view.Display; import android.view.MotionEvent; import android.view.View; @@ -232,6 +233,9 @@ public class Workspace extends SmoothPagedView private int mLastReorderX = -1; private int mLastReorderY = -1; + private SparseArray mSavedStates; + private final ArrayList mRestoredPages = new ArrayList(); + // These variables are used for storing the initial and final values during workspace animations private int mSavedScrollX; private float mSavedRotationY; @@ -3410,6 +3414,32 @@ public class Workspace extends SmoothPagedView Launcher.setScreen(mCurrentPage); } + @Override + protected void dispatchRestoreInstanceState(SparseArray container) { + // We don't dispatch restoreInstanceState to our children using this code path. + // Some pages will be restored immediately as their items are bound immediately, and + // others we will need to wait until after their items are bound. + mSavedStates = container; + } + + public void restoreInstanceStateForChild(int child) { + if (mSavedStates != null) { + mRestoredPages.add(child); + CellLayout cl = (CellLayout) getChildAt(child); + cl.restoreInstanceState(mSavedStates); + } + } + + public void restoreInstanceStateForRemainingPages() { + int count = getChildCount(); + for (int i = 0; i < count; i++) { + if (!mRestoredPages.contains(i)) { + restoreInstanceStateForChild(i); + } + } + mRestoredPages.clear(); + } + @Override public void scrollLeft() { if (!isSmall() && !mIsSwitchingState) { -- cgit v1.2.3 From c93e5ae12018bb214099ff88a48cc21580aec4c3 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 23 Jul 2012 20:48:26 -0700 Subject: Binding AllApps synchronously. (Bug 6855061) - Also ensuring that we restore to the settling page index if it is in motion Change-Id: I9c6760383113f7614f6cb962ab6562b0e7eb7138 --- .../android/launcher2/AppsCustomizePagedView.java | 30 +++++++------ .../android/launcher2/AppsCustomizeTabHost.java | 7 +-- src/com/android/launcher2/Launcher.java | 51 +++++++++++----------- src/com/android/launcher2/LauncherModel.java | 10 ++++- src/com/android/launcher2/PagedViewWidget.java | 27 +++++++++--- .../launcher2/PagedViewWithDraggableItems.java | 2 +- 6 files changed, 76 insertions(+), 51 deletions(-) diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index a50836168..8cb169e17 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -528,18 +528,22 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen super.onMeasure(widthMeasureSpec, heightMeasureSpec); } - public void onPackagesUpdated() { - // TODO: this isn't ideal, but we actually need to delay here. This call is triggered - // by a broadcast receiver, and in order for it to work correctly, we need to know that - // the AppWidgetService has already received and processed the same broadcast. Since there - // is no guarantee about ordering of broadcast receipt, we just delay here. This is a - // workaround until we add a callback from AppWidgetService to AppWidgetHost when widget - // packages are added, updated or removed. - postDelayed(new Runnable() { - public void run() { - updatePackages(); - } - }, 1500); + public void onPackagesUpdated(boolean immediate) { + if (immediate) { + updatePackages(); + } else { + // TODO: this isn't ideal, but we actually need to delay here. This call is triggered + // by a broadcast receiver, and in order for it to work correctly, we need to know that + // the AppWidgetService has already received and processed the same broadcast. Since there + // is no guarantee about ordering of broadcast receipt, we just delay here. This is a + // workaround until we add a callback from AppWidgetService to AppWidgetHost when widget + // packages are added, updated or removed. + postDelayed(new Runnable() { + public void run() { + updatePackages(); + } + }, 1500); + } } public void updatePackages() { @@ -578,7 +582,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen @Override public void onClick(View v) { // When we have exited all apps or are in transition, disregard clicks - if (!mLauncher.isAllAppsCustomizeOpen() || + if (!mLauncher.isAllAppsVisible() || mLauncher.getWorkspace().isSwitchingState()) return; if (v instanceof PagedViewIcon) { diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java index 9fa2f3237..c88b5a24a 100644 --- a/src/com/android/launcher2/AppsCustomizeTabHost.java +++ b/src/com/android/launcher2/AppsCustomizeTabHost.java @@ -81,7 +81,7 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona * reflects the new content (but doesn't do the animation and logic associated with changing * tabs manually). */ - private void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) { + void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) { onTabChangedStart(); onTabChangedEnd(type); } @@ -158,10 +158,11 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona if (contentWidth > 0 && mTabs.getLayoutParams().width != contentWidth) { // Set the width and show the tab bar mTabs.getLayoutParams().width = contentWidth; - post(mRelayoutAndMakeVisible); + mRelayoutAndMakeVisible.run(); } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } - super.onMeasure(widthMeasureSpec, heightMeasureSpec); } public boolean onInterceptTouchEvent(MotionEvent ev) { diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index ae2ca3b47..38085e029 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -371,7 +371,7 @@ public final class Launcher extends Activity // Update customization drawer _after_ restoring the states if (mAppsCustomizeContent != null) { - mAppsCustomizeContent.onPackagesUpdated(); + mAppsCustomizeContent.onPackagesUpdated(true); } if (PROFILE_STARTUP) { @@ -890,10 +890,8 @@ public final class Launcher extends Activity if (mAppsCustomizeTabHost != null) { String curTab = savedState.getString("apps_customize_currentTab"); if (curTab != null) { - // We set this directly so that there is no delay before the tab is set - mAppsCustomizeContent.setContentType( + mAppsCustomizeTabHost.setContentTypeImmediate( mAppsCustomizeTabHost.getContentTypeForTabTag(curTab)); - mAppsCustomizeTabHost.setCurrentTabByTag(curTab); mAppsCustomizeContent.loadAssociatedPages( mAppsCustomizeContent.getCurrentPage()); } @@ -1424,7 +1422,7 @@ public final class Launcher extends Activity @Override protected void onSaveInstanceState(Bundle outState) { - outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getCurrentPage()); + outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getNextPage()); super.onSaveInstanceState(outState); outState.putInt(RUNTIME_STATE, mState.ordinal()); @@ -1808,7 +1806,7 @@ public final class Launcher extends Activity @Override public void onBackPressed() { - if (mState == State.APPS_CUSTOMIZE) { + if (isAllAppsVisible()) { showWorkspace(true); } else if (mWorkspace.getOpenFolder() != null) { Folder openFolder = mWorkspace.getOpenFolder(); @@ -1881,7 +1879,7 @@ public final class Launcher extends Activity handleFolderClick(fi); } } else if (v == mAllAppsButton) { - if (mState == State.APPS_CUSTOMIZE) { + if (isAllAppsVisible()) { showWorkspace(true); } else { onClickAllAppsButton(v); @@ -2285,7 +2283,7 @@ public final class Launcher extends Activity // Now a part of LauncherModel.Callbacks. Used to reorder loading steps. public boolean isAllAppsVisible() { - return (mState == State.APPS_CUSTOMIZE); + return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE); } public boolean isAllAppsButtonRank(int rank) { @@ -2312,7 +2310,7 @@ public final class Launcher extends Activity void disableWallpaperIfInAllApps() { // Only disable it if we are in all apps - if (mState == State.APPS_CUSTOMIZE) { + if (isAllAppsVisible()) { if (mAppsCustomizeTabHost != null && !mAppsCustomizeTabHost.isTransitioning()) { updateWallpaperVisibility(false); @@ -2753,7 +2751,7 @@ public final class Launcher extends Activity } void enterSpringLoadedDragMode() { - if (mState == State.APPS_CUSTOMIZE) { + if (isAllAppsVisible()) { hideAppsCustomizeHelper(State.APPS_CUSTOMIZE_SPRING_LOADED, true, true, null); hideDockDivider(); mState = State.APPS_CUSTOMIZE_SPRING_LOADED; @@ -2827,10 +2825,6 @@ public final class Launcher extends Activity // TODO } - public boolean isAllAppsCustomizeOpen() { - return mState == State.APPS_CUSTOMIZE; - } - /** * Shows the hotseat area. */ @@ -3460,23 +3454,30 @@ public final class Launcher extends Activity * Implementation of the method from LauncherModel.Callbacks. */ public void bindAllApplications(final ArrayList apps) { + Runnable setAllAppsRunnable = new Runnable() { + public void run() { + if (mAppsCustomizeContent != null) { + mAppsCustomizeContent.setApps(apps); + } + } + }; + // Remove the progress bar entirely; we could also make it GONE // but better to remove it since we know it's not going to be used View progressBar = mAppsCustomizeTabHost. findViewById(R.id.apps_customize_progress_bar); if (progressBar != null) { ((ViewGroup)progressBar.getParent()).removeView(progressBar); + + // We just post the call to setApps so the user sees the progress bar + // disappear-- otherwise, it just looks like the progress bar froze + // which doesn't look great + mAppsCustomizeTabHost.post(setAllAppsRunnable); + } else { + // If we did not initialize the spinner in onCreate, then we can directly set the + // list of applications without waiting for any progress bars views to be hidden. + setAllAppsRunnable.run(); } - // We just post the call to setApps so the user sees the progress bar - // disappear-- otherwise, it just looks like the progress bar froze - // which doesn't look great - mAppsCustomizeTabHost.post(new Runnable() { - public void run() { - if (mAppsCustomizeContent != null) { - mAppsCustomizeContent.setApps(apps); - } - } - }); } /** @@ -3531,7 +3532,7 @@ public final class Launcher extends Activity */ public void bindPackagesUpdated() { if (mAppsCustomizeContent != null) { - mAppsCustomizeContent.onPackagesUpdated(); + mAppsCustomizeContent.onPackagesUpdated(false); } } diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 40a9e21dc..92be7e4df 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -1686,7 +1686,7 @@ public class LauncherModel extends BroadcastReceiver { @SuppressWarnings("unchecked") final ArrayList list = (ArrayList) mAllAppsList.data.clone(); - mHandler.post(new Runnable() { + Runnable r = new Runnable() { public void run() { final long t = SystemClock.uptimeMillis(); final Callbacks callbacks = tryGetCallbacks(oldCallbacks); @@ -1698,7 +1698,13 @@ public class LauncherModel extends BroadcastReceiver { + (SystemClock.uptimeMillis()-t) + "ms"); } } - }); + }; + boolean isRunningOnMainThread = !(sWorkerThread.getThreadId() == Process.myTid()); + if (oldCallbacks.isAllAppsVisible() && isRunningOnMainThread) { + r.run(); + } else { + mHandler.post(r); + } } private void loadAllAppsByBatch() { diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java index 66b7080d4..b804ab0a2 100644 --- a/src/com/android/launcher2/PagedViewWidget.java +++ b/src/com/android/launcher2/PagedViewWidget.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; +import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -44,6 +45,7 @@ public class PagedViewWidget extends LinearLayout { boolean mShortPressTriggered = false; static PagedViewWidget sShortpressTarget = null; boolean mIsAppWidget; + private final Rect mOriginalImagePadding = new Rect(); public PagedViewWidget(Context context) { this(context, null); @@ -63,6 +65,17 @@ public class PagedViewWidget extends LinearLayout { setClipToPadding(false); } + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + final ImageView image = (ImageView) findViewById(R.id.widget_preview); + mOriginalImagePadding.left = image.getPaddingLeft(); + mOriginalImagePadding.top = image.getPaddingTop(); + mOriginalImagePadding.right = image.getPaddingRight(); + mOriginalImagePadding.bottom = image.getPaddingBottom(); + } + public static void setDeletePreviewsWhenDetachedFromWindow(boolean value) { sDeletePreviewsWhenDetachedFromWindow = value; } @@ -79,7 +92,7 @@ public class PagedViewWidget extends LinearLayout { preview.getBitmap().recycle(); } image.setImageDrawable(null); - } + } } } @@ -117,8 +130,8 @@ public class PagedViewWidget extends LinearLayout { public int[] getPreviewSize() { final ImageView i = (ImageView) findViewById(R.id.widget_preview); int[] maxSize = new int[2]; - maxSize[0] = i.getWidth() - i.getPaddingLeft() - i.getPaddingRight(); - maxSize[1] = i.getHeight() - i.getPaddingTop(); + maxSize[0] = i.getWidth() - mOriginalImagePadding.left - mOriginalImagePadding.right; + maxSize[1] = i.getHeight() - mOriginalImagePadding.top; return maxSize; } @@ -132,10 +145,10 @@ public class PagedViewWidget extends LinearLayout { // center horizontally int[] imageSize = getPreviewSize(); int centerAmount = (imageSize[0] - preview.getIntrinsicWidth()) / 2; - image.setPadding(image.getPaddingLeft() + centerAmount, - image.getPaddingTop(), - image.getPaddingRight(), - image.getPaddingBottom()); + image.setPadding(mOriginalImagePadding.left + centerAmount, + mOriginalImagePadding.top, + mOriginalImagePadding.right, + mOriginalImagePadding.bottom); } image.setAlpha(1f); image.mAllowRequestLayout = true; diff --git a/src/com/android/launcher2/PagedViewWithDraggableItems.java b/src/com/android/launcher2/PagedViewWithDraggableItems.java index 22fd82b69..9cdd74f24 100644 --- a/src/com/android/launcher2/PagedViewWithDraggableItems.java +++ b/src/com/android/launcher2/PagedViewWithDraggableItems.java @@ -105,7 +105,7 @@ public abstract class PagedViewWithDraggableItems extends PagedView // Return early if we are still animating the pages if (mNextPage != INVALID_PAGE) return false; // When we have exited all apps or are in transition, disregard long clicks - if (!mLauncher.isAllAppsCustomizeOpen() || + if (!mLauncher.isAllAppsVisible() || mLauncher.getWorkspace().isSwitchingState()) return false; // Return if global dragging is not enabled if (!mLauncher.isDraggingEnabled()) return false; -- cgit v1.2.3 From 8ed3752f03d4b6c27297fa4fc9d4e153df47bbf3 Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Fri, 13 Jul 2012 15:59:15 -0700 Subject: Fix issue where widget resize frame overlaps widget (issue 6493388) Change-Id: Ib1e53a7df49b26ecb19880e58b19876b80cfb12c --- .../android/launcher2/AppWidgetResizeFrame.java | 24 ++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java index 882468624..f94ad019f 100644 --- a/src/com/android/launcher2/AppWidgetResizeFrame.java +++ b/src/com/android/launcher2/AppWidgetResizeFrame.java @@ -53,6 +53,9 @@ public class AppWidgetResizeFrame extends FrameLayout { private int mBackgroundPadding; private int mTouchTargetWidth; + private int mTopTouchRegionAdjustment = 0; + private int mBottomTouchRegionAdjustment = 0; + int[] mDirectionVector = new int[2]; final int SNAP_DURATION = 150; @@ -139,10 +142,12 @@ public class AppWidgetResizeFrame extends FrameLayout { public boolean beginResizeIfPointInRegion(int x, int y) { boolean horizontalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0; boolean verticalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0; + mLeftBorderActive = (x < mTouchTargetWidth) && horizontalActive; mRightBorderActive = (x > getWidth() - mTouchTargetWidth) && horizontalActive; - mTopBorderActive = (y < mTouchTargetWidth) && verticalActive; - mBottomBorderActive = (y > getHeight() - mTouchTargetWidth) && verticalActive; + mTopBorderActive = (y < mTouchTargetWidth + mTopTouchRegionAdjustment) && verticalActive; + mBottomBorderActive = (y > getHeight() - mTouchTargetWidth + mBottomTouchRegionAdjustment) + && verticalActive; boolean anyBordersActive = mLeftBorderActive || mRightBorderActive || mTopBorderActive || mBottomBorderActive; @@ -378,13 +383,20 @@ public class AppWidgetResizeFrame extends FrameLayout { int newX = mWidgetView.getLeft() - mBackgroundPadding + xOffset + mWidgetPaddingLeft; int newY = mWidgetView.getTop() - mBackgroundPadding + yOffset + mWidgetPaddingTop; - // We need to make sure the frame stays within the bounds of the CellLayout + // We need to make sure the frame's touchable regions lie fully within the bounds of the + // DragLayer. We allow the actual handles to be clipped, but we shift the touch regions + // down accordingly to provide a proper touch target. if (newY < 0) { - newHeight -= -newY; - newY = 0; + // In this case we shift the touch region down to start at the top of the DragLayer + mTopTouchRegionAdjustment = -newY; + } else { + mTopTouchRegionAdjustment = 0; } if (newY + newHeight > mDragLayer.getHeight()) { - newHeight -= newY + newHeight - mDragLayer.getHeight(); + // In this case we shift the touch region up to end at the bottom of the DragLayer + mBottomTouchRegionAdjustment = -(newY + newHeight - mDragLayer.getHeight()); + } else { + mBottomTouchRegionAdjustment = 0; } if (!animate) { -- cgit v1.2.3 From fa4086ddd7ab9dd98e3ffef798a655ec07e37e14 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 25 Jul 2012 16:18:49 -0700 Subject: Fixing issue where selected tab did not match AllApps page upon rotation. Change-Id: I4f32ca7cca042b94bdaea5cf259c397404546e0d --- src/com/android/launcher2/AppsCustomizeTabHost.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java index c88b5a24a..144aad98f 100644 --- a/src/com/android/launcher2/AppsCustomizeTabHost.java +++ b/src/com/android/launcher2/AppsCustomizeTabHost.java @@ -49,7 +49,6 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona private ViewGroup mTabs; private ViewGroup mTabsContainer; private AppsCustomizePagedView mAppsCustomizePane; - private boolean mSuppressContentCallback = false; private FrameLayout mAnimationBuffer; private LinearLayout mContent; @@ -82,16 +81,17 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona * tabs manually). */ void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) { + setOnTabChangedListener(null); onTabChangedStart(); onTabChangedEnd(type); + setCurrentTabByTag(getTabTagForContentType(type)); + setOnTabChangedListener(this); } void selectAppsTab() { setContentTypeImmediate(AppsCustomizePagedView.ContentType.Applications); - setCurrentTabByTag(APPS_TAB_TAG); } void selectWidgetsTab() { setContentTypeImmediate(AppsCustomizePagedView.ContentType.Widgets); - setCurrentTabByTag(WIDGETS_TAB_TAG); } /** @@ -208,10 +208,6 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona @Override public void onTabChanged(String tabId) { final AppsCustomizePagedView.ContentType type = getContentTypeForTabTag(tabId); - if (mSuppressContentCallback) { - mSuppressContentCallback = false; - return; - } // Animate the changing of the tab content by fading pages in and out final Resources res = getResources(); @@ -302,8 +298,9 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona } public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) { - mSuppressContentCallback = true; + setOnTabChangedListener(null); setCurrentTabByTag(getTabTagForContentType(type)); + setOnTabChangedListener(this); } /** -- cgit v1.2.3 From 2efda95e5a8f1b3ef78b209a9259f7040bbf16be Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 27 Jul 2012 16:57:01 -0700 Subject: Fixing landscape delete drop target padding. Change-Id: I17ee4c69f2f4b154a2dc19416a97d1d91b45b53a --- res/values-sw600dp-land/dimens.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml index 109372950..4bf751939 100644 --- a/res/values-sw600dp-land/dimens.xml +++ b/res/values-sw600dp-land/dimens.xml @@ -31,6 +31,7 @@ 82dp + 20dip 12dp -- cgit v1.2.3