Merge branch 'master' into froyo-release
diff --git a/Android.mk b/Android.mk
index 1522742..dc72ec6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,7 +28,6 @@
 
 LOCAL_OVERRIDES_PACKAGES := Home
 
-LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags
 
 include $(BUILD_PACKAGE)
diff --git a/proguard.flags b/proguard.flags
index fb145aa..5d72ef3 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -3,4 +3,6 @@
   public void nextScreen(android.view.View);
 }
 
--keep class com.android.launcher2.AllApps3D.Defines
+-keep class com.android.launcher2.AllApps3D$Defines {
+  *;
+}
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ec4fd95..73c6a8a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -113,16 +113,25 @@
     <string name="menu_settings">Settings</string>
 
     <!-- Permissions: -->
+    <skip />
+    <!-- Permission short label -->
     <string name="permlab_install_shortcut">install shortcuts</string>
+    <!-- Permission description -->
     <string name="permdesc_install_shortcut">Allows an application to add
         shortcuts without user intervention.</string>
+    <!-- Permission short label -->
     <string name="permlab_uninstall_shortcut">uninstall shortcuts</string>
+    <!-- Permission description -->
     <string name="permdesc_uninstall_shortcut">Allows an application to remove
         shortcuts without user intervention.</string>
+    <!-- Permission short label -->
     <string name="permlab_read_settings">read Home settings and shortcuts</string>
+    <!-- Permission description -->
     <string name="permdesc_read_settings">Allows an application to read the settings and
         shortcuts in Home.</string>
+    <!-- Permission short label -->
     <string name="permlab_write_settings">write Home settings and shortcuts</string>
+    <!-- Permission description -->
     <string name="permdesc_write_settings">Allows an application to change the settings and
         shortcuts in Home.</string>
 
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index f7cb749..1f48f5f 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -551,9 +551,9 @@
         mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);
         mAllAppsGrid.setLauncher(this);
         mAllAppsGrid.setDragController(dragController);
-        ((View)mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
+        ((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
         // Manage focusability manually since this thing is always visible
-        ((View)mAllAppsGrid).setFocusable(false); 
+        ((View) mAllAppsGrid).setFocusable(false); 
 
         mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
         final Workspace workspace = mWorkspace;
@@ -1707,8 +1707,8 @@
     void showAllApps(boolean animated) {
         mAllAppsGrid.zoom(1.0f, animated);
 
-        ((View)mAllAppsGrid).setFocusable(true);
-        ((View)mAllAppsGrid).requestFocus();
+        ((View) mAllAppsGrid).setFocusable(true);
+        ((View) mAllAppsGrid).requestFocus();
         
         // TODO: fade these two too
         mDeleteZone.setVisibility(View.GONE);
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index cc59538..c6813c3 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -624,15 +624,21 @@
 
             /**
              * Gets the callbacks object.  If we've been stopped, or if the launcher object
-             * has somehow been garbage collected, return null instead.
+             * has somehow been garbage collected, return null instead.  Pass in the Callbacks
+             * object that was around when the deferred message was scheduled, and if there's
+             * a new Callbacks object around then also return null.  This will save us from
+             * calling onto it with data that will be ignored.
              */
-            Callbacks tryGetCallbacks() {
+            Callbacks tryGetCallbacks(Callbacks oldCallbacks) {
                 synchronized (mLock) {
                     if (mStopped) {
                         return null;
                     }
 
                     final Callbacks callbacks = mCallbacks.get();
+                    if (callbacks != oldCallbacks) {
+                        return null;
+                    }
                     if (callbacks == null) {
                         Log.w(TAG, "no mCallbacks");
                         return null;
@@ -897,8 +903,8 @@
 
                 // Don't use these two variables in any of the callback runnables.
                 // Otherwise we hold a reference to them.
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks == null) {
+                final Callbacks oldCallbacks = mCallbacks.get();
+                if (oldCallbacks == null) {
                     // This launcher has exited and nobody bothered to tell us.  Just bail.
                     Log.w(TAG, "LoaderThread running with no launcher");
                     return;
@@ -908,7 +914,7 @@
                 // Tell the workspace that we're about to start firing items at it
                 mHandler.post(new Runnable() {
                     public void run() {
-                        Callbacks callbacks = tryGetCallbacks();
+                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                         if (callbacks != null) {
                             callbacks.startBinding();
                         }
@@ -921,7 +927,7 @@
                     final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i);
                     mHandler.post(new Runnable() {
                         public void run() {
-                            Callbacks callbacks = tryGetCallbacks();
+                            Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                             if (callbacks != null) {
                                 callbacks.bindItems(mItems, start, start+chunkSize);
                             }
@@ -930,7 +936,7 @@
                 }
                 mHandler.post(new Runnable() {
                     public void run() {
-                        Callbacks callbacks = tryGetCallbacks();
+                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                         if (callbacks != null) {
                             callbacks.bindFolders(mFolders);
                         }
@@ -949,7 +955,7 @@
                 // but since getCurrentScreen() just returns the int, we should be okay.  This
                 // is just a hint for the order, and if it's wrong, we'll be okay.
                 // TODO: instead, we should have that push the current screen into here.
-                final int currentScreen = callbacks.getCurrentWorkspaceScreen();
+                final int currentScreen = oldCallbacks.getCurrentWorkspaceScreen();
                 N = mAppWidgets.size();
                 // once for the current screen
                 for (int i=0; i<N; i++) {
@@ -957,7 +963,7 @@
                     if (widget.screen == currentScreen) {
                         mHandler.post(new Runnable() {
                             public void run() {
-                                Callbacks callbacks = tryGetCallbacks();
+                                Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                                 if (callbacks != null) {
                                     callbacks.bindAppWidget(widget);
                                 }
@@ -971,7 +977,7 @@
                     if (widget.screen != currentScreen) {
                         mHandler.post(new Runnable() {
                             public void run() {
-                                Callbacks callbacks = tryGetCallbacks();
+                                Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                                 if (callbacks != null) {
                                     callbacks.bindAppWidget(widget);
                                 }
@@ -982,7 +988,7 @@
                 // Tell the workspace that we're done.
                 mHandler.post(new Runnable() {
                     public void run() {
-                        Callbacks callbacks = tryGetCallbacks();
+                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                         if (callbacks != null) {
                             callbacks.finishBindingItems();
                         }
@@ -1006,7 +1012,7 @@
                 final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
                 mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
 
-                final Callbacks callbacks = tryGetCallbacks();
+                final Callbacks callbacks = mCallbacks.get();
                 if (callbacks == null) {
                     return;
                 }
@@ -1042,12 +1048,13 @@
                             = (ArrayList<ApplicationInfo>) mAllAppsList.data.clone();
                     // We're adding this now, so clear out this so we don't re-send them.
                     mAllAppsList.added = new ArrayList<ApplicationInfo>();
+                    final Callbacks old = mCallbacks.get();
                     mHandler.post(new Runnable() {
                         public void run() {
                             final long t = SystemClock.uptimeMillis();
                             final int count = results.size();
 
-                            Callbacks callbacks = tryGetCallbacks();
+                            Callbacks callbacks = tryGetCallbacks(old);
                             if (callbacks != null) {
                                 callbacks.bindAllApplications(results);
                             }