Workarounds for a couple crashes. (Bug 5612584, Bug 5613438)

Change-Id: I9669d830a10cc98291737f3f1d561c846c408289
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index af5141f..c55853e 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -37,7 +37,6 @@
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.TableMaskFilter;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -45,6 +44,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -168,7 +168,7 @@
  * The Apps/Customize page that displays all the applications, widgets, and shortcuts.
  */
 public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
-        AllAppsView, View.OnClickListener, DragSource {
+        AllAppsView, View.OnClickListener, View.OnKeyListener, DragSource {
     static final String LOG_TAG = "AppsCustomizePagedView";
 
     /**
@@ -515,6 +515,10 @@
         }
     }
 
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        return FocusHelper.handleAppsCustomizeKeyEvent(v,  keyCode, event);
+    }
+
     /*
      * PagedViewWithDraggableItems implementation
      */
@@ -663,14 +667,16 @@
 
     private void updateCurrentTab(int currentPage) {
         AppsCustomizeTabHost tabHost = getTabHost();
-        String tag = tabHost.getCurrentTabTag();
-        if (tag != null) {
-            if (currentPage >= mNumAppsPages &&
-                    !tag.equals(tabHost.getTabTagForContentType(ContentType.Widgets))) {
-                tabHost.setCurrentTabFromContent(ContentType.Widgets);
-            } else if (currentPage < mNumAppsPages &&
-                    !tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) {
-                tabHost.setCurrentTabFromContent(ContentType.Applications);
+        if (tabHost != null) {
+            String tag = tabHost.getCurrentTabTag();
+            if (tag != null) {
+                if (currentPage >= mNumAppsPages &&
+                        !tag.equals(tabHost.getTabTagForContentType(ContentType.Widgets))) {
+                    tabHost.setCurrentTabFromContent(ContentType.Widgets);
+                } else if (currentPage < mNumAppsPages &&
+                        !tag.equals(tabHost.getTabTagForContentType(ContentType.Applications))) {
+                    tabHost.setCurrentTabFromContent(ContentType.Applications);
+                }
             }
         }
     }
@@ -720,6 +726,7 @@
             icon.setOnClickListener(this);
             icon.setOnLongClickListener(this);
             icon.setOnTouchListener(this);
+            icon.setOnKeyListener(this);
 
             int index = i - startIndex;
             int x = index % mCellCountX;
@@ -1075,6 +1082,7 @@
             widget.setOnClickListener(this);
             widget.setOnLongClickListener(this);
             widget.setOnTouchListener(this);
+            widget.setOnKeyListener(this);
 
             // Layout each widget
             int ix = i % mWidgetCountX;
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 41f8d7e..7772f44 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -202,6 +202,17 @@
 
                 // Take the visible pages and re-parent them temporarily to mAnimatorBuffer
                 // and then cross fade to the new pages
+                int[] visiblePageRange = new int[2];
+                mAppsCustomizePane.getVisiblePages(visiblePageRange);
+                if (visiblePageRange[0] == -1 && visiblePageRange[1] == -1) {
+                    // If we can't get the visible page ranges, then just skip the animation
+                    reloadCurrentPage();
+                    return;
+                }
+                ArrayList<View> visiblePages = new ArrayList<View>();
+                for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
+                    visiblePages.add(mAppsCustomizePane.getPageAt(i));
+                }
 
                 // We want the pages to be rendered in exactly the same way as they were when
                 // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer
@@ -209,16 +220,15 @@
                 // parameters to be correct for each of the pages
                 mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0);
 
-                int[] visiblePageRange = new int[2];
-                mAppsCustomizePane.getVisiblePages(visiblePageRange);
-                ArrayList<View> visiblePages = new ArrayList<View>();
-                for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
-                    visiblePages.add(mAppsCustomizePane.getPageAt(i));
-                }
                 // mAppsCustomizePane renders its children in reverse order, so
                 // add the pages to mAnimationBuffer in reverse order to match that behavior
                 for (int i = visiblePages.size() - 1; i >= 0; i--) {
                     View child = visiblePages.get(i);
+                    if (child instanceof PagedViewCellLayout) {
+                        ((PagedViewCellLayout) child).resetChildrenOnKeyListeners();
+                    } else if (child instanceof PagedViewGridLayout) {
+                        ((PagedViewGridLayout) child).resetChildrenOnKeyListeners();
+                    }
                     PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false);
                     mAppsCustomizePane.removeView(child);
                     PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 14ef53f..49c25b5 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -752,17 +752,18 @@
             getVisiblePages(mTempVisiblePagesRange);
             final int leftScreen = mTempVisiblePagesRange[0];
             final int rightScreen = mTempVisiblePagesRange[1];
+            if (leftScreen != -1 && rightScreen != -1) {
+                final long drawingTime = getDrawingTime();
+                // Clip to the bounds
+                canvas.save();
+                canvas.clipRect(mScrollX, mScrollY, mScrollX + mRight - mLeft,
+                        mScrollY + mBottom - mTop);
 
-            final long drawingTime = getDrawingTime();
-            // Clip to the bounds
-            canvas.save();
-            canvas.clipRect(mScrollX, mScrollY, mScrollX + mRight - mLeft,
-                    mScrollY + mBottom - mTop);
-
-            for (int i = rightScreen; i >= leftScreen; i--) {
-                drawChild(canvas, getPageAt(i), drawingTime);
+                for (int i = rightScreen; i >= leftScreen; i--) {
+                    drawChild(canvas, getPageAt(i), drawingTime);
+                }
+                canvas.restore();
             }
-            canvas.restore();
         }
     }
 
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 6266ca2..ef39813 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -151,6 +151,16 @@
         mChildren.removeViewAt(index);
     }
 
+    /**
+     * Clears all the key listeners for the individual icons.
+     */
+    public void resetChildrenOnKeyListeners() {
+        int childCount = mChildren.getChildCount();
+        for (int j = 0; j < childCount; ++j) {
+            mChildren.getChildAt(j).setOnKeyListener(null);
+        }
+    }
+
     @Override
     public int getPageChildCount() {
         return mChildren.getChildCount();
diff --git a/src/com/android/launcher2/PagedViewGridLayout.java b/src/com/android/launcher2/PagedViewGridLayout.java
index 01d7593..5c32e09 100644
--- a/src/com/android/launcher2/PagedViewGridLayout.java
+++ b/src/com/android/launcher2/PagedViewGridLayout.java
@@ -46,6 +46,16 @@
         return mCellCountY;
     }
 
+    /**
+     * Clears all the key listeners for the individual widgets.
+     */
+    public void resetChildrenOnKeyListeners() {
+        int childCount = getChildCount();
+        for (int j = 0; j < childCount; ++j) {
+            getChildAt(j).setOnKeyListener(null);
+        }
+    }
+
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // PagedView currently has issues with different-sized pages since it calculates the
         // offset of each page to scroll to before it updates the actual size of each page
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index 3cc7786..b03d867 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -155,18 +155,6 @@
     }
 
     @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        return FocusHelper.handleAppsCustomizeKeyEvent(this, keyCode, event)
-                || super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        return FocusHelper.handleAppsCustomizeKeyEvent(this, keyCode, event)
-                || super.onKeyUp(keyCode, event);
-    }
-
-    @Override
     public boolean isChecked() {
         return mIsChecked;
     }
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index d3541ff..18fa249 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -183,18 +183,6 @@
     }
 
     @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        return FocusHelper.handleAppsCustomizeKeyEvent(this, keyCode, event)
-                || super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        return FocusHelper.handleAppsCustomizeKeyEvent(this, keyCode, event)
-                || super.onKeyUp(keyCode, event);
-    }
-
-    @Override
     protected void onDraw(Canvas canvas) {
         if (mAlpha > 0) {
             super.onDraw(canvas);