Remove use of private APIs

Change-Id: I3e28763075f8e92391796dc009214c9fa8f50008
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 2935cea..bb5365e 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -576,9 +576,10 @@
             @Override
             public void run() {
                 mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId();
-                AppWidgetManager.getInstance(mLauncher).bindAppWidgetId(mWidgetLoadingId,
-                        info.componentName);
-                mWidgetCleanupState = WIDGET_BOUND;
+                if (AppWidgetManager.getInstance(mLauncher)
+                            .bindAppWidgetIdIfAllowed(mWidgetLoadingId, info.componentName)) {
+                    mWidgetCleanupState = WIDGET_BOUND;
+                }
             }
         };
         post(mBindWidgetRunnable);
@@ -586,8 +587,8 @@
         mInflateWidgetRunnable = new Runnable() {
             @Override
             public void run() {
-                AppWidgetHostView hostView =
-                        mLauncher.getAppWidgetHost().createView(mContext, mWidgetLoadingId, pInfo);
+                AppWidgetHostView hostView = mLauncher.
+                        getAppWidgetHost().createView(getContext(), mWidgetLoadingId, pInfo);
                 info.boundWidget = hostView;
                 mWidgetCleanupState = WIDGET_INFLATED;
                 hostView.setVisibility(INVISIBLE);
@@ -1462,7 +1463,7 @@
 
                 // If the view has 0 alpha, we set it to be invisible so as to prevent
                 // it from accepting touches
-                if (alpha < ViewConfiguration.ALPHA_THRESHOLD) {
+                if (alpha == 0) {
                     v.setVisibility(INVISIBLE);
                 } else if (v.getVisibility() != VISIBLE) {
                     v.setVisibility(VISIBLE);
@@ -1687,6 +1688,6 @@
             count = mNumWidgetPages;
         }
 
-        return String.format(mContext.getString(stringId), page + 1, count);
+        return String.format(getContext().getString(stringId), page + 1, count);
     }
 }
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index 21842da..34b7c09 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -102,7 +102,7 @@
         setup();
 
         final ViewGroup tabsContainer = (ViewGroup) findViewById(R.id.tabs_container);
-        final TabWidget tabs = (TabWidget) findViewById(com.android.internal.R.id.tabs);
+        final TabWidget tabs = getTabWidget();
         final AppsCustomizePagedView appsCustomizePane = (AppsCustomizePagedView)
                 findViewById(R.id.apps_customize_pane_content);
         mTabs = tabs;
@@ -123,12 +123,12 @@
         // Create the tabs
         TextView tabView;
         String label;
-        label = mContext.getString(R.string.all_apps_button_label);
+        label = getContext().getString(R.string.all_apps_button_label);
         tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
         tabView.setText(label);
         tabView.setContentDescription(label);
         addTab(newTabSpec(APPS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
-        label = mContext.getString(R.string.widgets_tab_label);
+        label = getContext().getString(R.string.widgets_tab_label);
         tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
         tabView.setText(label);
         tabView.setContentDescription(label);
diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java
index 526fda7..ddc4b9f 100644
--- a/src/com/android/launcher2/BubbleTextView.java
+++ b/src/com/android/launcher2/BubbleTextView.java
@@ -99,7 +99,7 @@
 
     @Override
     protected boolean setFrame(int left, int top, int right, int bottom) {
-        if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
+        if (getLeft() != left || getRight() != right || getTop() != top || getBottom() != bottom) {
             mBackgroundSizeChanged = true;
         }
         return super.setFrame(left, top, right, bottom);
@@ -268,11 +268,11 @@
     public void draw(Canvas canvas) {
         final Drawable background = mBackground;
         if (background != null) {
-            final int scrollX = mScrollX;
-            final int scrollY = mScrollY;
+            final int scrollX = getScrollX();
+            final int scrollY = getScrollY();
 
             if (mBackgroundSizeChanged) {
-                background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
+                background.setBounds(0, 0,  getRight() - getLeft(), getBottom() - getTop());
                 mBackgroundSizeChanged = false;
             }
 
@@ -296,8 +296,9 @@
         getPaint().setShadowLayer(SHADOW_LARGE_RADIUS, 0.0f, SHADOW_Y_OFFSET, SHADOW_LARGE_COLOUR);
         super.draw(canvas);
         canvas.save(Canvas.CLIP_SAVE_FLAG);
-        canvas.clipRect(mScrollX, mScrollY + getExtendedPaddingTop(), mScrollX + getWidth(),
-                mScrollY + getHeight(), Region.Op.INTERSECT);
+        canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
+                getScrollX() + getWidth(),
+                getScrollY() + getHeight(), Region.Op.INTERSECT);
         getPaint().setShadowLayer(SHADOW_SMALL_RADIUS, 0.0f, 0.0f, SHADOW_SMALL_COLOUR);
         super.draw(canvas);
         canvas.restore();
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index a48a815..a19ccea 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -173,7 +173,7 @@
 
     public CellLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mDragEnforcer = new DropTarget.DragEnforcer(mContext);
+        mDragEnforcer = new DropTarget.DragEnforcer(context);
 
         // A ViewGroup usually does not draw, but CellLayout needs to draw a rectangle to show
         // the user where a dragged item will land when dropped.
@@ -747,8 +747,8 @@
     public void setTagToCellInfoForPoint(int touchX, int touchY) {
         final CellInfo cellInfo = mCellInfo;
         Rect frame = mRect;
-        final int x = touchX + mScrollX;
-        final int y = touchY + mScrollY;
+        final int x = touchX + getScrollX();
+        final int y = touchY + getScrollY();
         final int count = mShortcutsAndWidgets.getChildCount();
 
         boolean found = false;
@@ -766,7 +766,7 @@
                 // The child hit rect is relative to the CellLayoutChildren parent, so we need to
                 // offset that by this CellLayout's padding to test an (x,y) point that is relative
                 // to this view.
-                frame.offset(mPaddingLeft, mPaddingTop);
+                frame.offset(getPaddingLeft(), getPaddingTop());
                 frame.inset((int) (frame.width() * (1f - scale) / 2),
                         (int) (frame.height() * (1f - scale) / 2));
 
@@ -955,8 +955,8 @@
         }
         int left = getPaddingLeft();
         int top = getPaddingTop();
-        int right = left + getWidth() - mPaddingLeft - mPaddingRight;
-        int bottom = top + getHeight() - mPaddingTop - mPaddingBottom;
+        int right = left + getWidth() - getPaddingLeft() - getPaddingRight();
+        int bottom = top + getHeight() - getPaddingTop() - getPaddingBottom();
         r.set(left, top, right, bottom);
         return r;
     }
@@ -979,8 +979,8 @@
         int numHeightGaps = mCountY - 1;
 
         if (mOriginalWidthGap < 0 || mOriginalHeightGap < 0) {
-            int hSpace = widthSpecSize - mPaddingLeft - mPaddingRight;
-            int vSpace = heightSpecSize - mPaddingTop - mPaddingBottom;
+            int hSpace = widthSpecSize - getPaddingLeft() - getPaddingRight();
+            int vSpace = heightSpecSize - getPaddingTop() - getPaddingBottom();
             int hFreeSpace = hSpace - (mCountX * mOriginalCellWidth);
             int vFreeSpace = vSpace - (mCountY * mOriginalCellHeight);
             mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
@@ -995,9 +995,9 @@
         int newWidth = widthSpecSize;
         int newHeight = heightSpecSize;
         if (widthSpecMode == MeasureSpec.AT_MOST) {
-            newWidth = mPaddingLeft + mPaddingRight + (mCountX * mCellWidth) +
+            newWidth = getPaddingLeft() + getPaddingRight() + (mCountX * mCellWidth) +
                 ((mCountX - 1) * mWidthGap);
-            newHeight = mPaddingTop + mPaddingBottom + (mCountY * mCellHeight) +
+            newHeight = getPaddingTop() + getPaddingBottom() + (mCountY * mCellHeight) +
                 ((mCountY - 1) * mHeightGap);
             setMeasuredDimension(newWidth, newHeight);
         }
@@ -1005,10 +1005,10 @@
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
-            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth - mPaddingLeft -
-                    mPaddingRight, MeasureSpec.EXACTLY);
-            int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight - mPaddingTop -
-                    mPaddingBottom, MeasureSpec.EXACTLY);
+            int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth - getPaddingLeft() -
+                    getPaddingRight(), MeasureSpec.EXACTLY);
+            int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight - getPaddingTop() -
+                    getPaddingBottom(), MeasureSpec.EXACTLY);
             child.measure(childWidthMeasureSpec, childheightMeasureSpec);
         }
         setMeasuredDimension(newWidth, newHeight);
@@ -1019,8 +1019,8 @@
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
-            child.layout(mPaddingLeft, mPaddingTop,
-                    r - l - mPaddingRight, b - t - mPaddingBottom);
+            child.layout(getPaddingLeft(), getPaddingTop(),
+                    r - l - getPaddingRight(), b - t - getPaddingBottom());
         }
     }
 
@@ -2762,12 +2762,12 @@
     }
 
     public int getDesiredWidth() {
-        return mPaddingLeft + mPaddingRight + (mCountX * mCellWidth) +
+        return getPaddingLeft() + getPaddingRight() + (mCountX * mCellWidth) +
                 (Math.max((mCountX - 1), 0) * mWidthGap);
     }
 
     public int getDesiredHeight()  {
-        return mPaddingTop + mPaddingBottom + (mCountY * mCellHeight) +
+        return getPaddingTop() + getPaddingBottom() + (mCountY * mCellHeight) +
                 (Math.max((mCountY - 1), 0) * mHeightGap);
     }
 
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index f71baec..69ed053 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -28,6 +28,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -43,7 +44,7 @@
 /**
  * A ViewGroup that coordinates dragging across its descendants
  */
-public class DragLayer extends FrameLayout {
+public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChangeListener {
     private DragController mDragController;
     private int[] mTmpXY = new int[2];
 
@@ -83,6 +84,7 @@
         // Disable multitouch across the workspace/all apps/customize tray
         setMotionEventSplittingEnabled(false);
         setChildrenDrawingOrderEnabled(true);
+        setOnHierarchyChangeListener(this);
     }
 
     public void setup(Launcher launcher, DragController controller) {
@@ -164,7 +166,9 @@
         if (currentFolder == null) {
             return false;
         } else {
-            if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
+                AccessibilityManager accessibilityManager = (AccessibilityManager)
+                        getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+            if (accessibilityManager.isTouchExplorationEnabled()) {
                 final int action = ev.getAction();
                 boolean isOverFolder;
                 switch (action) {
@@ -197,13 +201,15 @@
     }
 
     private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) {
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+        AccessibilityManager accessibilityManager = (AccessibilityManager)
+                getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+        if (accessibilityManager.isEnabled()) {
             int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close;
             AccessibilityEvent event = AccessibilityEvent.obtain(
                     AccessibilityEvent.TYPE_VIEW_FOCUSED);
             onInitializeAccessibilityEvent(event);
-            event.getText().add(mContext.getString(stringId));
-            AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event);
+            event.getText().add(getContext().getString(stringId));
+            accessibilityManager.sendAccessibilityEvent(event);
         }
     }
 
@@ -674,14 +680,12 @@
     }
 
     @Override
-    protected void onViewAdded(View child) {
-        super.onViewAdded(child);
+    public void onChildViewAdded(View parent, View child) {
         updateChildIndices();
     }
 
     @Override
-    protected void onViewRemoved(View child) {
-        super.onViewRemoved(child);
+    public void onChildViewRemoved(View parent, View child) {
         updateChildIndices();
     }
 
diff --git a/src/com/android/launcher2/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java
index 0066440..e9f986d 100644
--- a/src/com/android/launcher2/FocusHelper.java
+++ b/src/com/android/launcher2/FocusHelper.java
@@ -85,8 +85,7 @@
      */
     static boolean handleAppsCustomizeTabKeyEvent(View v, int keyCode, KeyEvent e) {
         final TabHost tabHost = findTabHostParent(v);
-        final ViewGroup contents = (ViewGroup)
-                tabHost.findViewById(com.android.internal.R.id.tabcontent);
+        final ViewGroup contents = tabHost.getTabContentView();
         final View shop = tabHost.findViewById(R.id.market_button);
 
         final int action = e.getAction();
@@ -137,7 +136,7 @@
         final PagedViewGridLayout parent = (PagedViewGridLayout) w.getParent();
         final PagedView container = (PagedView) parent.getParent();
         final TabHost tabHost = findTabHostParent(container);
-        final TabWidget tabs = (TabWidget) tabHost.findViewById(com.android.internal.R.id.tabs);
+        final TabWidget tabs = tabHost.getTabWidget();
         final int widgetIndex = parent.indexOfChild(w);
         final int widgetCount = parent.getChildCount();
         final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parent));
@@ -297,7 +296,7 @@
         // PagedViewCellLayout/PagedViewCellLayoutChildren relationship
         final PagedView container = (PagedView) parentLayout.getParent();
         final TabHost tabHost = findTabHostParent(container);
-        final TabWidget tabs = (TabWidget) tabHost.findViewById(com.android.internal.R.id.tabs);
+        final TabWidget tabs = tabHost.getTabWidget();
         final int iconIndex = itemContainer.indexOfChild(v);
         final int itemCount = itemContainer.getChildCount();
         final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parentLayout));
@@ -442,8 +441,7 @@
 
         final FocusOnlyTabWidget parent = (FocusOnlyTabWidget) v.getParent();
         final TabHost tabHost = findTabHostParent(parent);
-        final ViewGroup contents = (ViewGroup)
-                tabHost.findViewById(com.android.internal.R.id.tabcontent);
+        final ViewGroup contents = tabHost.getTabContentView();
         final int tabCount = parent.getTabCount();
         final int tabIndex = parent.getChildTabIndex(v);
 
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 01939f8..0389264 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -127,7 +127,7 @@
         }
 
         mInputMethodManager = (InputMethodManager)
-                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
+                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 
         mExpandDuration = res.getInteger(R.integer.config_folderAnimDuration);
 
@@ -250,7 +250,7 @@
 
         if (commit) {
             sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                    String.format(mContext.getString(R.string.folder_renamed), newTitle));
+                    String.format(getContext().getString(R.string.folder_renamed), newTitle));
         }
         // In order to clear the focus from the text field, we set the focus on ourself. This
         // ensures that every time the field is clicked, focus is gained, giving reliable behavior.
@@ -379,7 +379,7 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                        String.format(mContext.getString(R.string.folder_opened),
+                        String.format(getContext().getString(R.string.folder_opened),
                         mContent.getCountX(), mContent.getCountY()));
                 mState = STATE_ANIMATING;
             }
@@ -399,11 +399,13 @@
     }
 
     private void sendCustomAccessibilityEvent(int type, String text) {
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+        AccessibilityManager accessibilityManager = (AccessibilityManager)
+                getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+        if (accessibilityManager.isEnabled()) {
             AccessibilityEvent event = AccessibilityEvent.obtain(type);
             onInitializeAccessibilityEvent(event);
             event.getText().add(text);
-            AccessibilityManager.getInstance(mContext).sendAccessibilityEvent(event);
+            accessibilityManager.sendAccessibilityEvent(event);
         }
     }
 
@@ -430,7 +432,7 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                        mContext.getString(R.string.folder_closed));
+                        getContext().getString(R.string.folder_closed));
                 mState = STATE_ANIMATING;
             }
         });
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index 2377f30..4a71329 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -601,7 +601,7 @@
 
     public void onTitleChanged(CharSequence title) {
         mFolderName.setText(title.toString());
-        setContentDescription(String.format(mContext.getString(R.string.folder_name_format),
+        setContentDescription(String.format(getContext().getString(R.string.folder_name_format),
                 title));
     }
 
diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java
index 1faaeef..56d194d 100644
--- a/src/com/android/launcher2/HolographicOutlineHelper.java
+++ b/src/com/android/launcher2/HolographicOutlineHelper.java
@@ -61,8 +61,6 @@
         sMediumInnerBlurMaskFilter = new BlurMaskFilter(scale * 2.0f, BlurMaskFilter.Blur.NORMAL);
     }
 
-    private static final MaskFilter sCoarseClipTable = TableMaskFilter.CreateClipTable(0, 200);
-
     private int[] mTempOffset = new int[2];
 
     HolographicOutlineHelper() {
@@ -99,24 +97,6 @@
     }
 
     /**
-     * Apply an outer blur to the given bitmap.
-     * You should use OUTER_BLUR_RADIUS to ensure that the bitmap is big enough to draw
-     * the blur without clipping.
-     */
-    void applyOuterBlur(Bitmap bitmap, Canvas canvas, int color) {
-        mBlurPaint.setMaskFilter(sThickOuterBlurMaskFilter);
-        Bitmap glow = bitmap.extractAlpha(mBlurPaint, mTempOffset);
-
-        // Use the clip table to make the glow heavier closer to the outline
-        mHolographicPaint.setMaskFilter(sCoarseClipTable);
-        mHolographicPaint.setAlpha(150);
-        mHolographicPaint.setColor(color);
-
-        canvas.drawBitmap(glow, mTempOffset[0], mTempOffset[1], mHolographicPaint);
-        glow.recycle();
-    }
-
-    /**
      * Applies a more expensive and accurate outline to whatever is currently drawn in a specified
      * bitmap.
      */
diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java
index efa9fac..1e42f1b 100644
--- a/src/com/android/launcher2/IconCache.java
+++ b/src/com/android/launcher2/IconCache.java
@@ -64,7 +64,7 @@
 
     public Drawable getFullResDefaultActivityIcon() {
         return getFullResIcon(Resources.getSystem(),
-                com.android.internal.R.mipmap.sym_def_app_icon);
+                android.R.mipmap.sym_def_app_icon);
     }
 
     public Drawable getFullResIcon(Resources resources, int iconId) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index e2b86a4..2829e3c 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -133,6 +133,8 @@
     private static final int REQUEST_PICK_APPWIDGET = 9;
     private static final int REQUEST_PICK_WALLPAPER = 10;
 
+    private static final int REQUEST_BIND_APPWIDGET = 11;
+
     static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate";
 
     static final int SCREEN_COUNT = 5;
@@ -250,7 +252,7 @@
     private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2];
 
     static final ArrayList<String> sDumpLogs = new ArrayList<String>();
-    PendingAddWidgetInfo mWidgetBeingConfigured = null;
+    PendingAddWidgetInfo mWidgetBeingBoundOrConfigured = null;
 
     // We only want to get the SharedPreferences once since it does an FS stat each time we get
     // it from the context.
@@ -545,7 +547,18 @@
     }
 
     @Override
-    protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
+    protected void onActivityResult(
+            final int requestCode, final int resultCode, final Intent data) {
+        if (requestCode == REQUEST_BIND_APPWIDGET) {
+            int appWidgetId = data != null ?
+                    data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;
+            if (resultCode == RESULT_CANCELED) {
+                completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId);
+            } else if (resultCode == RESULT_OK) {
+                addAppWidgetImpl(appWidgetId, mWidgetBeingBoundOrConfigured);
+            }
+            return;
+        }
         boolean delayExitSpringLoadedMode = false;
         boolean isWidgetDrop = (requestCode == REQUEST_PICK_APPWIDGET ||
                 requestCode == REQUEST_CREATE_APPWIDGET);
@@ -585,15 +598,16 @@
     }
 
     private void completeTwoStageWidgetDrop(final int resultCode, final int appWidgetId) {
-        CellLayout cellLayout = (CellLayout) mWorkspace.getChildAt(mWidgetBeingConfigured.screen);
+        CellLayout cellLayout =
+                (CellLayout) mWorkspace.getChildAt(mWidgetBeingBoundOrConfigured.screen);
         Runnable onCompleteRunnable = null;
         int animationType = 0;
 
         if (resultCode == RESULT_OK) {
             animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;
             final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,
-                    mWidgetBeingConfigured.info);
-            mWidgetBeingConfigured.boundWidget = layout;
+                    mWidgetBeingBoundOrConfigured.info);
+            mWidgetBeingBoundOrConfigured.boundWidget = layout;
             onCompleteRunnable = new Runnable() {
                 @Override
                 public void run() {
@@ -613,10 +627,10 @@
                 }
             };
         }
-        mWorkspace.animateWidgetDrop(mWidgetBeingConfigured, cellLayout,
+        mWorkspace.animateWidgetDrop(mWidgetBeingBoundOrConfigured, cellLayout,
                 (DragView) mDragLayer.getAnimatedView(), onCompleteRunnable,
-                animationType, mWidgetBeingConfigured.boundWidget, true);
-        mWidgetBeingConfigured = null;
+                animationType, mWidgetBeingBoundOrConfigured.boundWidget, true);
+        mWidgetBeingBoundOrConfigured = null;
     }
 
     @Override
@@ -1541,7 +1555,7 @@
                 }
             }
             startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
-            mWidgetBeingConfigured = info;
+            mWidgetBeingBoundOrConfigured = info;
         } else {
             // Otherwise just add it
             completeAddAppWidget(appWidgetId, info.container, info.screen, info.boundWidget, appWidget);
@@ -1605,11 +1619,19 @@
         int appWidgetId;
         if (hostView != null) {
             appWidgetId = hostView.getAppWidgetId();
+            addAppWidgetImpl(appWidgetId, info);
         } else {
             appWidgetId = getAppWidgetHost().allocateAppWidgetId();
-            AppWidgetManager.getInstance(this).bindAppWidgetId(appWidgetId, info.componentName);
+            mWidgetBeingBoundOrConfigured = info;
+            if (mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.componentName)) {
+                addAppWidgetImpl(appWidgetId, info);
+            } else {
+                Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
+                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
+                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
+                startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
+            }
         }
-        addAppWidgetImpl(appWidgetId, info);
     }
 
     void processShortcut(Intent intent) {
diff --git a/src/com/android/launcher2/LauncherProvider.java b/src/com/android/launcher2/LauncherProvider.java
index c8fb09e..d69dd34 100644
--- a/src/com/android/launcher2/LauncherProvider.java
+++ b/src/com/android/launcher2/LauncherProvider.java
@@ -16,13 +16,6 @@
 
 package com.android.launcher2;
 
-import com.android.internal.util.XmlUtils;
-import com.android.launcher.R;
-import com.android.launcher2.LauncherSettings.Favorites;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import android.app.SearchManager;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
@@ -54,6 +47,12 @@
 import android.util.Log;
 import android.util.Xml;
 
+import com.android.launcher.R;
+import com.android.launcher2.LauncherSettings.Favorites;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -684,15 +683,18 @@
                         db.update(TABLE_FAVORITES, values, updateWhere, null);
 
                         if (favoriteType == Favorites.ITEM_TYPE_WIDGET_CLOCK) {
-                            appWidgetManager.bindAppWidgetId(appWidgetId,
+                            // TODO: check return value
+                            appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
                                     new ComponentName("com.android.alarmclock",
                                     "com.android.alarmclock.AnalogAppWidgetProvider"));
                         } else if (favoriteType == Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) {
-                            appWidgetManager.bindAppWidgetId(appWidgetId,
+                            // TODO: check return value
+                            appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
                                     new ComponentName("com.android.camera",
                                     "com.android.camera.PhotoAppWidgetProvider"));
                         } else if (favoriteType == Favorites.ITEM_TYPE_WIDGET_SEARCH) {
-                            appWidgetManager.bindAppWidgetId(appWidgetId,
+                            // TODO: check return value
+                            appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,
                                     getSearchWidgetProvider());
                         }
                     } catch (RuntimeException ex) {
@@ -711,6 +713,24 @@
             }
         }
 
+        private static final void beginDocument(XmlPullParser parser, String firstElementName)
+                throws XmlPullParserException, IOException {
+            int type;
+            while ((type = parser.next()) != parser.START_TAG
+                    && type != parser.END_DOCUMENT) {
+                ;
+            }
+
+            if (type != parser.START_TAG) {
+                throw new XmlPullParserException("No start tag found");
+            }
+
+            if (!parser.getName().equals(firstElementName)) {
+                throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
+                        ", expected " + firstElementName);
+            }
+        }
+
         /**
          * Loads the default set of favorite packages from an xml file.
          *
@@ -729,7 +749,7 @@
             try {
                 XmlResourceParser parser = mContext.getResources().getXml(workspaceResourceId);
                 AttributeSet attrs = Xml.asAttributeSet(parser);
-                XmlUtils.beginDocument(parser, TAG_FAVORITES);
+                beginDocument(parser, TAG_FAVORITES);
 
                 final int depth = parser.getDepth();
 
@@ -989,7 +1009,8 @@
 
                 allocatedAppWidgets = true;
 
-                appWidgetManager.bindAppWidgetId(appWidgetId, cn);
+                // TODO: need to check return value
+                appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, cn);
             } catch (RuntimeException ex) {
                 Log.e(TAG, "Problem allocating appWidgetId", ex);
             }
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 1fc39f6..83b688d 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -50,7 +50,7 @@
  * An abstraction of the original Workspace which supports browsing through a
  * sequential list of "pages"
  */
-public abstract class PagedView extends ViewGroup {
+public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
     private static final String TAG = "PagedView";
     private static final boolean DEBUG = false;
     protected static final int INVALID_PAGE = -1;
@@ -132,7 +132,7 @@
     protected int mUnboundedScrollX;
     protected int[] mTempVisiblePagesRange = new int[2];
 
-    // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+    // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise
     // it is equal to the scaled overscroll position. We use a separate value so as to prevent
     // the screens from continuing to translate beyond the normal bounds.
     protected int mOverScrollX;
@@ -158,7 +158,7 @@
     // to switch to a new page
     protected boolean mUsePagingTouchSlop = true;
 
-    // If true, the subclass should directly update mScrollX itself in its computeScroll method
+    // If true, the subclass should directly update scrollX itself in its computeScroll method
     // (SmoothPagedView does this)
     protected boolean mDeferScrollUpdate = false;
 
@@ -241,6 +241,7 @@
         mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
         mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * mDensity);
         mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * mDensity);
+        setOnHierarchyChangeListener(this);
     }
 
     public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
@@ -362,7 +363,7 @@
 
     @Override
     public void scrollBy(int x, int y) {
-        scrollTo(mUnboundedScrollX + x, mScrollY + y);
+        scrollTo(mUnboundedScrollX + x, getScrollY() + y);
     }
 
     @Override
@@ -392,8 +393,8 @@
     protected boolean computeScrollHelper() {
         if (mScroller.computeScrollOffset()) {
             // Don't bother scrolling if the page does not need to be moved
-            if (mScrollX != mScroller.getCurrX()
-                || mScrollY != mScroller.getCurrY()
+            if (getScrollX() != mScroller.getCurrX()
+                || getScrollY() != mScroller.getCurrY()
                 || mOverScrollX != mScroller.getCurrX()) {
                 scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
             }
@@ -417,7 +418,9 @@
             }
 
             // Notify the user when the page changes
-            if (AccessibilityManager.getInstance(getContext()).isEnabled()) {
+            AccessibilityManager accessibilityManager = (AccessibilityManager)
+                    getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
+            if (accessibilityManager.isEnabled()) {
                 AccessibilityEvent ev =
                     AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
                 ev.getText().add(getCurrentPageDescription());
@@ -455,8 +458,8 @@
         int heightSize = MeasureSpec.getSize(heightMeasureSpec);
         int maxChildHeight = 0;
 
-        final int verticalPadding = mPaddingTop + mPaddingBottom;
-        final int horizontalPadding = mPaddingLeft + mPaddingRight;
+        final int verticalPadding = getPaddingTop() + getPaddingBottom();
+        final int horizontalPadding = getPaddingLeft() + getPaddingRight();
 
 
         // The children are given the same width and height as the workspace
@@ -514,7 +517,7 @@
 
     protected void scrollToNewPageWithoutMovingPages(int newCurrentPage) {
         int newX = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage);
-        int delta = newX - mScrollX;
+        int delta = newX - getScrollX();
 
         final int pageCount = getChildCount();
         for (int i = 0; i < pageCount; i++) {
@@ -545,7 +548,7 @@
         int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY);
         requestLayout();
         measure(widthSpec, heightSpec);
-        layout(mLeft, mTop, mRight, mBottom);
+        layout(getLeft(), getTop(), getRight(), getBottom());
         for (int i = 0; i < childCount; i++) {
             final View child = getPageAt(i);
             child.setX(childrenX[i]);
@@ -569,7 +572,7 @@
         }
 
         if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
-        final int verticalPadding = mPaddingTop + mPaddingBottom;
+        final int verticalPadding = getPaddingTop() + getPaddingBottom();
         final int childCount = getChildCount();
         int childLeft = 0;
         if (childCount > 0) {
@@ -595,7 +598,7 @@
             if (child.getVisibility() != View.GONE) {
                 final int childWidth = getScaledMeasuredWidth(child);
                 final int childHeight = child.getMeasuredHeight();
-                int childTop = mPaddingTop;
+                int childTop = getPaddingTop();
                 if (mCenterPagesVertically) {
                     childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
                 }
@@ -637,9 +640,7 @@
     }
 
     @Override
-    protected void onViewAdded(View child) {
-        super.onViewAdded(child);
-
+    public void onChildViewAdded(View parent, View child) {
         // This ensures that when children are added, they get the correct transforms / alphas
         // in accordance with any scroll effects.
         mForceScreenScrolled = true;
@@ -647,6 +648,10 @@
         invalidateCachedOffsets();
     }
 
+    @Override
+    public void onChildViewRemoved(View parent, View child) {
+    }
+
     protected void invalidateCachedOffsets() {
         int count = getChildCount();
         if (count == 0) {
@@ -691,8 +696,8 @@
         if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
             return mChildRelativeOffsets[index];
         } else {
-            final int padding = mPaddingLeft + mPaddingRight;
-            final int offset = mPaddingLeft +
+            final int padding = getPaddingLeft() + getPaddingRight();
+            final int offset = getPaddingLeft() +
                     (getMeasuredWidth() - padding - getChildWidth(index)) / 2;
             if (mChildRelativeOffsets != null) {
                 mChildRelativeOffsets[index] = offset;
@@ -702,8 +707,8 @@
     }
 
     protected int getScaledRelativeChildOffset(int index) {
-        final int padding = mPaddingLeft + mPaddingRight;
-        final int offset = mPaddingLeft + (getMeasuredWidth() - padding -
+        final int padding = getPaddingLeft() + getPaddingRight();
+        final int offset = getPaddingLeft() + (getMeasuredWidth() - padding -
                 getScaledMeasuredWidth(getPageAt(index))) / 2;
         return offset;
     }
@@ -726,14 +731,15 @@
             int rightScreen = 0;
             View currPage = getPageAt(leftScreen);
             while (leftScreen < pageCount - 1 &&
-                    currPage.getX() + currPage.getWidth() - currPage.getPaddingRight() < mScrollX) {
+                    currPage.getX() + currPage.getWidth() -
+                    currPage.getPaddingRight() < getScrollX()) {
                 leftScreen++;
                 currPage = getPageAt(leftScreen);
             }
             rightScreen = leftScreen;
             currPage = getPageAt(rightScreen + 1);
             while (rightScreen < pageCount - 1 &&
-                    currPage.getX() - currPage.getPaddingLeft() < mScrollX + screenWidth) {
+                    currPage.getX() - currPage.getPaddingLeft() < getScrollX() + screenWidth) {
                 rightScreen++;
                 currPage = getPageAt(rightScreen + 1);
             }
@@ -748,8 +754,8 @@
     @Override
     protected void dispatchDraw(Canvas canvas) {
         int halfScreenSize = getMeasuredWidth() / 2;
-        // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
-        // it is equal to the scaled overscroll position.
+        // mOverScrollX is equal to getScrollX() when we're within the normal scroll range.
+        // Otherwise it is equal to the scaled overscroll position.
         int screenCenter = mOverScrollX + halfScreenSize;
 
         if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
@@ -770,8 +776,8 @@
                 final long drawingTime = getDrawingTime();
                 // Clip to the bounds
                 canvas.save();
-                canvas.clipRect(mScrollX, mScrollY, mScrollX + mRight - mLeft,
-                        mScrollY + mBottom - mTop);
+                canvas.clipRect(getScrollX(), getScrollY(), getScrollX() + getRight() - getLeft(),
+                        getScrollY() + getBottom() - getTop());
 
                 // On certain graphics drivers, if you draw to a off-screen buffer that's not
                 // used, it can lead to poor performance. We were running into this when
@@ -781,9 +787,7 @@
                 // View.INVISIBLE, preventing re-drawing of their hardware layer
                 for (int i = getChildCount() - 1; i >= 0; i--) {
                     final View v = getPageAt(i);
-
-                    if (leftScreen <= i && i <= rightScreen &&
-                            v.getAlpha() > ViewConfiguration.ALPHA_THRESHOLD) {
+                    if (leftScreen <= i && i <= rightScreen && v.getAlpha() > 0) {
                         v.setVisibility(VISIBLE);
                         drawChild(canvas, v, drawingTime);
                     } else {
@@ -1043,7 +1047,7 @@
                 mTotalMotionX += Math.abs(mLastMotionX - x);
                 mLastMotionX = x;
                 mLastMotionXRemainder = 0;
-                mTouchX = mScrollX;
+                mTouchX = getScrollX();
                 mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                 pageBeginMoving();
             }
@@ -1102,10 +1106,10 @@
         int overScrollAmount = (int) Math.round(f * screenSize);
         if (amount < 0) {
             mOverScrollX = overScrollAmount;
-            mScrollX = 0;
+            super.scrollTo(0, getScrollY());
         } else {
             mOverScrollX = mMaxScrollX + overScrollAmount;
-            mScrollX = mMaxScrollX;
+            super.scrollTo(mMaxScrollX, getScrollY());
         }
         invalidate();
     }
@@ -1126,10 +1130,10 @@
         int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
         if (amount < 0) {
             mOverScrollX = overScrollAmount;
-            mScrollX = 0;
+            super.scrollTo(0, getScrollY());
         } else {
             mOverScrollX = mMaxScrollX + overScrollAmount;
-            mScrollX = mMaxScrollX;
+            super.scrollTo(mMaxScrollX, getScrollY());
         }
         invalidate();
     }
@@ -1392,7 +1396,7 @@
     int getPageNearestToCenterOfScreen() {
         int minDistanceFromScreenCenter = Integer.MAX_VALUE;
         int minDistanceFromScreenCenterIndex = -1;
-        int screenCenter = mScrollX + (getMeasuredWidth() / 2);
+        int screenCenter = getScrollX() + (getMeasuredWidth() / 2);
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; ++i) {
             View layout = (View) getPageAt(i);
@@ -1855,7 +1859,7 @@
 
     protected String getCurrentPageDescription() {
         int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
-        return String.format(mContext.getString(R.string.default_scroll_format),
+        return String.format(getContext().getString(R.string.default_scroll_format),
                 page + 1, getChildCount());
     }
 
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 9e5452b..6f73e63 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -193,8 +193,8 @@
         int numHeightGaps = mCellCountY - 1;
 
         if (mOriginalWidthGap < 0 || mOriginalHeightGap < 0) {
-            int hSpace = widthSpecSize - mPaddingLeft - mPaddingRight;
-            int vSpace = heightSpecSize - mPaddingTop - mPaddingBottom;
+            int hSpace = widthSpecSize - getPaddingLeft() - getPaddingRight();
+            int vSpace = heightSpecSize - getPaddingTop() - getPaddingBottom();
             int hFreeSpace = hSpace - (mCellCountX * mOriginalCellWidth);
             int vFreeSpace = vSpace - (mCellCountY * mOriginalCellHeight);
             mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
@@ -210,9 +210,9 @@
         int newWidth = widthSpecSize;
         int newHeight = heightSpecSize;
         if (widthSpecMode == MeasureSpec.AT_MOST) {
-            newWidth = mPaddingLeft + mPaddingRight + (mCellCountX * mCellWidth) +
+            newWidth = getPaddingLeft() + getPaddingRight() + (mCellCountX * mCellWidth) +
                 ((mCellCountX - 1) * mWidthGap);
-            newHeight = mPaddingTop + mPaddingBottom + (mCellCountY * mCellHeight) +
+            newHeight = getPaddingTop() + getPaddingBottom() + (mCellCountY * mCellHeight) +
                 ((mCellCountY - 1) * mHeightGap);
             setMeasuredDimension(newWidth, newHeight);
         }
@@ -221,11 +221,11 @@
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
             int childWidthMeasureSpec =
-                MeasureSpec.makeMeasureSpec(newWidth - mPaddingLeft -
-                        mPaddingRight, MeasureSpec.EXACTLY);
+                MeasureSpec.makeMeasureSpec(newWidth - getPaddingLeft() -
+                        getPaddingRight(), MeasureSpec.EXACTLY);
             int childheightMeasureSpec =
-                MeasureSpec.makeMeasureSpec(newHeight - mPaddingTop -
-                        mPaddingBottom, MeasureSpec.EXACTLY);
+                MeasureSpec.makeMeasureSpec(newHeight - getPaddingTop() -
+                        getPaddingBottom(), MeasureSpec.EXACTLY);
             child.measure(childWidthMeasureSpec, childheightMeasureSpec);
         }
 
@@ -233,7 +233,7 @@
     }
 
     int getContentWidth() {
-        return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight;
+        return getWidthBeforeFirstLayout() + getPaddingLeft() + getPaddingRight();
     }
 
     int getContentHeight() {
@@ -255,8 +255,8 @@
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
-            child.layout(mPaddingLeft, mPaddingTop,
-                r - l - mPaddingRight, b - t - mPaddingBottom);
+            child.layout(getPaddingLeft(), getPaddingTop(),
+                r - l - getPaddingRight(), b - t - getPaddingBottom());
         }
     }
 
@@ -327,7 +327,7 @@
     public int estimateCellHSpan(int width) {
         // We don't show the next/previous pages any more, so we use the full width, minus the
         // padding
-        int availWidth = width - (mPaddingLeft + mPaddingRight);
+        int availWidth = width - (getPaddingLeft() + getPaddingRight());
 
         // We know that we have to fit N cells with N-1 width gaps, so we just juggle to solve for N
         int n = Math.max(1, (availWidth + mWidthGap) / (mCellWidth + mWidthGap));
@@ -342,7 +342,7 @@
     public int estimateCellVSpan(int height) {
         // The space for a page is the height - top padding (current page) - bottom padding (current
         // page)
-        int availHeight = height - (mPaddingTop + mPaddingBottom);
+        int availHeight = height - (getPaddingTop() + getPaddingBottom());
 
         // We know that we have to fit N cells with N-1 height gaps, so we juggle to solve for N
         int n = Math.max(1, (availHeight + mHeightGap) / (mCellHeight + mHeightGap));
@@ -354,8 +354,8 @@
     /** Returns an estimated center position of the cell at the specified index */
     public int[] estimateCellPosition(int x, int y) {
         return new int[] {
-                mPaddingLeft + (x * mCellWidth) + (x * mWidthGap) + (mCellWidth / 2),
-                mPaddingTop + (y * mCellHeight) + (y * mHeightGap) + (mCellHeight / 2)
+                getPaddingLeft() + (x * mCellWidth) + (x * mWidthGap) + (mCellWidth / 2),
+                getPaddingTop() + (y * mCellHeight) + (y * mHeightGap) + (mCellHeight / 2)
         };
     }
 
diff --git a/src/com/android/launcher2/SmoothPagedView.java b/src/com/android/launcher2/SmoothPagedView.java
index e6414d9..7e47f1a 100644
--- a/src/com/android/launcher2/SmoothPagedView.java
+++ b/src/com/android/launcher2/SmoothPagedView.java
@@ -175,7 +175,7 @@
                 final float e = (float) Math.exp((now - mSmoothingTime) / SMOOTHING_CONSTANT);
 
                 final float dx = mTouchX - mUnboundedScrollX;
-                scrollTo(Math.round(mUnboundedScrollX + dx * e), mScrollY);
+                scrollTo(Math.round(mUnboundedScrollX + dx * e), getScrollY());
                 mSmoothingTime = now;
 
                 // Keep generating points as long as we're more than 1px away from the target
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index d2f050c..9370bf9 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -68,7 +68,7 @@
  */
 public class Workspace extends SmoothPagedView
         implements DropTarget, DragSource, DragScroller, View.OnTouchListener,
-        DragController.DragListener, LauncherTransitionable {
+        DragController.DragListener, LauncherTransitionable, ViewGroup.OnHierarchyChangeListener {
     private static final String TAG = "Launcher.Workspace";
 
     // Y rotation to apply to the workspace screens
@@ -322,6 +322,8 @@
         mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
         a.recycle();
 
+        setOnHierarchyChangeListener(this);
+
         LauncherModel.updateWorkspaceLayoutCells(cellCountX, cellCountY);
         setHapticFeedbackEnabled(false);
 
@@ -417,8 +419,7 @@
     }
 
     @Override
-    protected void onViewAdded(View child) {
-        super.onViewAdded(child);
+    public void onChildViewAdded(View parent, View child) {
         if (!(child instanceof CellLayout)) {
             throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
         }
@@ -428,6 +429,10 @@
         cl.enableHardwareLayers();
     }
 
+    @Override
+    public void onChildViewRemoved(View parent, View child) {
+    }
+
     /**
      * @return The open folder on the current screen, or null if there is none
      */
@@ -824,7 +829,7 @@
         int scrollRange = getScrollRange();
 
         // Again, we adjust the wallpaper offset to be consistent between values of mLayoutScale
-        float adjustedScrollX = Math.max(0, Math.min(mScrollX, mMaxScrollX));
+        float adjustedScrollX = Math.max(0, Math.min(getScrollX(), mMaxScrollX));
         adjustedScrollX *= mWallpaperScrollRatio;
         mLayoutScale = layoutScale;
 
@@ -1296,7 +1301,7 @@
         if (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground) {
             int alpha = (int) (mBackgroundAlpha * 255);
             mBackground.setAlpha(alpha);
-            mBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(),
+            mBackground.setBounds(getScrollX(), 0, getScrollX() + getMeasuredWidth(),
                     getMeasuredHeight());
             mBackground.draw(canvas);
         }
@@ -1318,9 +1323,9 @@
             final int pageHeight = getChildAt(0).getHeight();
 
             // Set the height of the outline to be the height of the page
-            final int offset = (height - pageHeight - mPaddingTop - mPaddingBottom) / 2;
-            final int paddingTop = mPaddingTop + offset;
-            final int paddingBottom = mPaddingBottom + offset;
+            final int offset = (height - pageHeight - getPaddingTop() - getPaddingBottom()) / 2;
+            final int paddingTop = getPaddingTop() + offset;
+            final int paddingBottom = getPaddingBottom() + offset;
 
             final int page = (mNextPage != INVALID_PAGE ? mNextPage : mCurrentPage);
             final CellLayout leftPage = (CellLayout) getChildAt(page - 1);
@@ -1328,13 +1333,13 @@
 
             if (leftPage != null && leftPage.getIsDragOverlapping()) {
                 final Drawable d = getResources().getDrawable(R.drawable.page_hover_left_holo);
-                d.setBounds(mScrollX, paddingTop, mScrollX + d.getIntrinsicWidth(),
+                d.setBounds(getScrollX(), paddingTop, getScrollX() + d.getIntrinsicWidth(),
                         height - paddingBottom);
                 d.draw(canvas);
             } else if (rightPage != null && rightPage.getIsDragOverlapping()) {
                 final Drawable d = getResources().getDrawable(R.drawable.page_hover_right_holo);
-                d.setBounds(mScrollX + width - d.getIntrinsicWidth(), paddingTop, mScrollX + width,
-                        height - paddingBottom);
+                d.setBounds(getScrollX() + width - d.getIntrinsicWidth(), paddingTop,
+                        getScrollX() + width, height - paddingBottom);
                 d.draw(canvas);
             }
         }
@@ -2545,12 +2550,12 @@
            v.getMatrix().invert(mTempInverseMatrix);
            cachedInverseMatrix = mTempInverseMatrix;
        }
-       int scrollX = mScrollX;
+       int scrollX = getScrollX();
        if (mNextPage != INVALID_PAGE) {
            scrollX = mScroller.getFinalX();
        }
        xy[0] = xy[0] + scrollX - v.getLeft();
-       xy[1] = xy[1] + mScrollY - v.getTop();
+       xy[1] = xy[1] + getScrollY() - v.getTop();
        cachedInverseMatrix.mapPoints(xy);
    }
 
@@ -2576,12 +2581,12 @@
     */
    void mapPointFromChildToSelf(View v, float[] xy) {
        v.getMatrix().mapPoints(xy);
-       int scrollX = mScrollX;
+       int scrollX = getScrollX();
        if (mNextPage != INVALID_PAGE) {
            scrollX = mScroller.getFinalX();
        }
        xy[0] -= (scrollX - v.getLeft());
-       xy[1] -= (mScrollY - v.getTop());
+       xy[1] -= (getScrollY() - v.getTop());
    }
 
    static private float squaredDistance(float[] point1, float[] point2) {
@@ -3713,7 +3718,7 @@
     @Override
     protected String getCurrentPageDescription() {
         int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
-        return String.format(mContext.getString(R.string.workspace_scroll_format),
+        return String.format(getContext().getString(R.string.workspace_scroll_format),
                 page + 1, getChildCount());
     }