Merge "Fix scrolling accessibility events sent from PagedView" into jb-ub-now-indigo-rose
diff --git a/Android.mk b/Android.mk
index e22d53c..3b1a244 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,7 +32,7 @@
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
 LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/
 
-LOCAL_SDK_VERSION := 17
+LOCAL_SDK_VERSION := 19
 
 LOCAL_PACKAGE_NAME := Launcher3
 #LOCAL_CERTIFICATE := shared
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index bb6a495..c4a67af 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -95,7 +95,7 @@
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Laman aplikasi %1$d dari %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Laman widget %1$d dari %2$d"</string>
     <string name="first_run_cling_title" msgid="7257389003637362144">"Selamat datang!"</string>
-    <string name="first_run_cling_description" msgid="6447072552696253358">"Serasa di rumah sendiri"</string>
+    <string name="first_run_cling_description" msgid="6447072552696253358">"Serasa di rumah sendiri."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Buat lebih banyak layar untuk aplikasi dan folder"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dfccd98..9f4f20b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -38,6 +38,9 @@
         <item quantity="one">%1$d selected</item>
         <item quantity="other">%1$d selected</item>
     </plurals>
+    <!-- Accessibility string used as a label for a particular wallpaper in the Wallpaper Picker list.
+         e.g. "Wallpaper 3 of 10" -->
+    <string name="wallpaper_accessibility_name">Wallpaper %1$d of %2$d</string>
 
     <!-- Label on button to delete wallpaper(s) -->
     <string name="wallpaper_delete">Delete</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 9f2a105..42704df 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -22,6 +22,7 @@
         <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
         <item name="android:windowFullscreen">true</item>
         <item name="android:windowActionBarOverlay">true</item>
+        <item name="android:windowTranslucentNavigation">true</item>
     </style>
 
     <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 72a6ce2..1d10553 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -1009,11 +1009,13 @@
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int offset = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() -
+                (mCountX * mCellWidth);
+        int left = getPaddingLeft() + (int) Math.ceil(offset / 2f);
+        int top = getPaddingTop();
         int count = getChildCount();
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
-            int left = getPaddingLeft();
-            int top = getPaddingTop();
             child.layout(left, top,
                     left + r - l,
                     top + b - t);
diff --git a/src/com/android/launcher3/CropView.java b/src/com/android/launcher3/CropView.java
index f68f739..c8b974d 100644
--- a/src/com/android/launcher3/CropView.java
+++ b/src/com/android/launcher3/CropView.java
@@ -197,13 +197,14 @@
             float squaredDist = (mFirstX - x) * (mFirstX - x) + (mFirstY - y) * (mFirstY - y);
             float slop = config.getScaledTouchSlop() * config.getScaledTouchSlop();
             long now = System.currentTimeMillis();
-            // only do this if it's a small movement
-            if (mTouchCallback != null &&
-                    squaredDist < slop &&
-                    now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
-                mTouchCallback.onTap();
+            if (mTouchCallback != null) {
+                // only do this if it's a small movement
+                if (squaredDist < slop &&
+                        now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
+                    mTouchCallback.onTap();
+                }
+                mTouchCallback.onTouchUp();
             }
-            mTouchCallback.onTouchUp();
         }
 
         if (!mTouchEnabled) {
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 8a6fbc1..065d7a7 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -460,7 +460,7 @@
                 lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
                 lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
                 lp.width = LayoutParams.WRAP_CONTENT;
-                lp.height = pageIndicatorHeightPx;
+                lp.height = LayoutParams.WRAP_CONTENT;
                 lp.bottomMargin = hotseatBarHeightPx;
                 pageIndicator.setLayoutParams(lp);
             }
diff --git a/src/com/android/launcher3/LiveWallpaperListAdapter.java b/src/com/android/launcher3/LiveWallpaperListAdapter.java
index 4b59794..54e0af7 100644
--- a/src/com/android/launcher3/LiveWallpaperListAdapter.java
+++ b/src/com/android/launcher3/LiveWallpaperListAdapter.java
@@ -93,6 +93,7 @@
         WallpaperPickerActivity.setWallpaperItemPaddingToZero((FrameLayout) view);
 
         LiveWallpaperTile wallpaperInfo = mWallpapers.get(position);
+        wallpaperInfo.setView(view);
         ImageView image = (ImageView) view.findViewById(R.id.wallpaper_image);
         ImageView icon = (ImageView) view.findViewById(R.id.wallpaper_icon);
         if (wallpaperInfo.mThumbnail != null) {
@@ -174,46 +175,10 @@
                 Intent launchIntent = new Intent(WallpaperService.SERVICE_INTERFACE);
                 launchIntent.setClassName(info.getPackageName(), info.getServiceName());
                 LiveWallpaperTile wallpaper = new LiveWallpaperTile(thumb, info, launchIntent);
-
-                // TODO: generate a default thumb
-                /*
-                final Resources res = mContext.getResources();
-                Canvas canvas = new Canvas();
-                Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
-                paint.setTextAlign(Paint.Align.CENTER);
-                BitmapDrawable galleryIcon = (BitmapDrawable) res.getDrawable(
-                        R.drawable.livewallpaper_placeholder);
-                if (thumb == null) {
-                    int thumbWidth = res.getDimensionPixelSize(
-                            R.dimen.live_wallpaper_thumbnail_width);
-                    int thumbHeight = res.getDimensionPixelSize(
-                            R.dimen.live_wallpaper_thumbnail_height);
-
-                    Bitmap thumbnail = Bitmap.createBitmap(thumbWidth, thumbHeight,
-                            Bitmap.Config.ARGB_8888);
-
-                    paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_background));
-                    canvas.setBitmap(thumbnail);
-                    canvas.drawPaint(paint);
-
-                    galleryIcon.setBounds(0, 0, thumbWidth, thumbHeight);
-                    galleryIcon.setGravity(Gravity.CENTER);
-                    galleryIcon.draw(canvas);
-
-                    String title = info.loadLabel(packageManager).toString();
-
-                    paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_text_color));
-                    paint.setTextSize(
-                            res.getDimensionPixelSize(R.dimen.live_wallpaper_thumbnail_text_size));
-
-                    canvas.drawText(title, (int) (thumbWidth * 0.5),
-                            thumbHeight - res.getDimensionPixelSize(
-                                    R.dimen.live_wallpaper_thumbnail_text_offset), paint);
-
-                    thumb = new BitmapDrawable(res, thumbnail);
-                }*/
                 publishProgress(wallpaper);
             }
+            // Send a null object to show loading is finished
+            publishProgress((LiveWallpaperTile) null);
 
             return null;
         }
@@ -221,6 +186,10 @@
         @Override
         protected void onProgressUpdate(LiveWallpaperTile...infos) {
             for (LiveWallpaperTile info : infos) {
+                if (info == null) {
+                    LiveWallpaperListAdapter.this.notifyDataSetChanged();
+                    break;
+                }
                 info.mThumbnail.setDither(true);
                 if (mWallpaperPosition < mWallpapers.size()) {
                     mWallpapers.set(mWallpaperPosition, info);
@@ -228,9 +197,6 @@
                     mWallpapers.add(info);
                 }
                 mWallpaperPosition++;
-                if (mWallpaperPosition == getCount()) {
-                    LiveWallpaperListAdapter.this.notifyDataSetChanged();
-                }
             }
         }
     }
diff --git a/src/com/android/launcher3/MarketUpdateReceiver.java b/src/com/android/launcher3/MarketUpdateReceiver.java
deleted file mode 100644
index c41bf3e..0000000
--- a/src/com/android/launcher3/MarketUpdateReceiver.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.util.Log;
-
-public class MarketUpdateReceiver extends BroadcastReceiver {
-    private static final String TAG = "MarketUpdateReceiver";
-
-    private static final String ACTION_PACKAGE_ENQUEUED =
-            "com.android.launcher.action.ACTION_PACKAGE_ENQUEUED";
-    private static final String ACTION_PACKAGE_DOWNLOADING =
-            "com.android.launcher.action.ACTION_PACKAGE_DOWNLOADING";
-    private static final String ACTION_PACKAGE_INSTALLING =
-            "com.android.launcher.action.ACTION_PACKAGE_INSTALLING";
-    private static final String ACTION_PACKAGE_DEQUEUED =
-            "com.android.launcher.action.ACTION_PACKAGE_DEQUEUED";
-
-    /** extra for {@link #ACTION_PACKAGE_ENQUEUED}, send on of the following values **/
-    private static final String EXTRA_KEY_REASON = "reason";
-    private static final String EXTRA_VALUE_REASON_INSTALL = "install";
-    private static final String EXTRA_VALUE_REASON_UPDATE = "update";
-    private static final String EXTRA_VALUE_REASON_RESTORE = "restore";
-
-    /** extra for {@link #ACTION_PACKAGE_DOWNLOADING}, send an int in the range [0-100]. **/
-    private static final String EXTRA_KEY_PROGRESS = "progress";
-
-    /**
-     * extra for {@link #ACTION_PACKAGE_DEQUEUED}
-     * send {@link android.app.Activity#RESULT_OK} on success.
-     * or {@link android.app.Activity#RESULT_CANCELED} if the package was abandoned.
-     * **/
-    private static final String EXTRA_KEY_STATUS =
-            "com.android.launcher.action.EXTRA_STATUS";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final String action = intent.getAction();
-        String pkgName = "none";
-        Uri uri = intent.getData();
-        if (uri != null) {
-            pkgName = uri.getSchemeSpecificPart();;
-        }
-        if (ACTION_PACKAGE_ENQUEUED.equals(action)) {
-            String reason = "unknown";
-            if (intent.hasExtra(EXTRA_KEY_REASON)) {
-                reason = intent.getStringExtra(EXTRA_KEY_REASON);
-            }
-            Log.d(TAG, "market has promised to " + reason + ": " + pkgName);
-        } else if (ACTION_PACKAGE_DOWNLOADING.equals(action)) {
-            int progress = intent.getIntExtra(EXTRA_KEY_PROGRESS, 0);
-            Log.d(TAG, "market is downloading (" + progress + "%): " + pkgName);
-        } else if (ACTION_PACKAGE_INSTALLING.equals(action)) {
-            Log.d(TAG, "market is installing: " + pkgName);
-        } else if ( ACTION_PACKAGE_DEQUEUED.equals(action)) {
-            boolean success = Activity.RESULT_OK == intent.getIntExtra(EXTRA_KEY_STATUS,
-                    Activity.RESULT_CANCELED);
-            if (success) {
-                Log.d(TAG, "market has installed: " + pkgName);
-            } else {
-                Log.d(TAG, "market has decided not to install: " + pkgName);
-            }
-        } else {
-            Log.d(TAG, "unknown message " + action);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 2182680..b209436 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -826,48 +826,50 @@
         for (int i = 0; i < childCount; i++) {
             // disallowing padding in paged view (just pass 0)
             final View child = getPageAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (child.getVisibility() != GONE) {
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
 
-            int childWidthMode;
-            int childHeightMode;
-            int childWidth;
-            int childHeight;
+                int childWidthMode;
+                int childHeightMode;
+                int childWidth;
+                int childHeight;
 
-            if (!lp.isFullScreenPage) {
-                if (lp.width == LayoutParams.WRAP_CONTENT) {
-                    childWidthMode = MeasureSpec.AT_MOST;
+                if (!lp.isFullScreenPage) {
+                    if (lp.width == LayoutParams.WRAP_CONTENT) {
+                        childWidthMode = MeasureSpec.AT_MOST;
+                    } else {
+                        childWidthMode = MeasureSpec.EXACTLY;
+                    }
+
+                    if (lp.height == LayoutParams.WRAP_CONTENT) {
+                        childHeightMode = MeasureSpec.AT_MOST;
+                    } else {
+                        childHeightMode = MeasureSpec.EXACTLY;
+                    }
+
+                    childWidth = widthSize - horizontalPadding;
+                    childHeight = heightSize - verticalPadding - mInsets.top - mInsets.bottom;
+                    mNormalChildHeight = childHeight;
+
                 } else {
                     childWidthMode = MeasureSpec.EXACTLY;
-                }
-
-                if (lp.height == LayoutParams.WRAP_CONTENT) {
-                    childHeightMode = MeasureSpec.AT_MOST;
-                } else {
                     childHeightMode = MeasureSpec.EXACTLY;
+
+                    if (mUseMinScale) {
+                        childWidth = getViewportWidth();
+                        childHeight = getViewportHeight();
+                    } else {
+                        childWidth = widthSize - getPaddingLeft() - getPaddingRight();
+                        childHeight = heightSize - getPaddingTop() - getPaddingBottom();
+                    }
                 }
 
-                childWidth = widthSize - horizontalPadding;
-                childHeight = heightSize - verticalPadding - mInsets.top - mInsets.bottom;
-                mNormalChildHeight = childHeight;
-
-            } else {
-                childWidthMode = MeasureSpec.EXACTLY;
-                childHeightMode = MeasureSpec.EXACTLY;
-
-                if (mUseMinScale) {
-                    childWidth = getViewportWidth();
-                    childHeight = getViewportHeight();
-                } else {
-                    childWidth = widthSize - getPaddingLeft() - getPaddingRight();
-                    childHeight = heightSize - getPaddingTop() - getPaddingBottom();
-                }
+                final int childWidthMeasureSpec =
+                        MeasureSpec.makeMeasureSpec(childWidth, childWidthMode);
+                    final int childHeightMeasureSpec =
+                        MeasureSpec.makeMeasureSpec(childHeight, childHeightMode);
+                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
             }
-
-            final int childWidthMeasureSpec =
-                    MeasureSpec.makeMeasureSpec(childWidth, childWidthMode);
-                final int childHeightMeasureSpec =
-                    MeasureSpec.makeMeasureSpec(childHeight, childHeightMode);
-            child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
         }
         setMeasuredDimension(scaledWidthSize, scaledHeightSize);
 
@@ -928,18 +930,18 @@
 
         for (int i = startIndex; i != endIndex; i += delta) {
             final View child = getPageAt(i);
-            LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            int childTop;
-            if (lp.isFullScreenPage) {
-                childTop = offsetY;
-            } else {
-                childTop = offsetY + getPaddingTop() + mInsets.top;
-                if (mCenterPagesVertically) {
-                    childTop += (getViewportHeight() - mInsets.top - mInsets.bottom - verticalPadding - child.getMeasuredHeight()) / 2;
-                }
-            }
-
             if (child.getVisibility() != View.GONE) {
+                LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                int childTop;
+                if (lp.isFullScreenPage) {
+                    childTop = offsetY;
+                } else {
+                    childTop = offsetY + getPaddingTop() + mInsets.top;
+                    if (mCenterPagesVertically) {
+                        childTop += (getViewportHeight() - mInsets.top - mInsets.bottom - verticalPadding - child.getMeasuredHeight()) / 2;
+                    }
+                }
+
                 final int childWidth = child.getMeasuredWidth();
                 final int childHeight = child.getMeasuredHeight();
 
diff --git a/src/com/android/launcher3/SavedWallpaperImages.java b/src/com/android/launcher3/SavedWallpaperImages.java
index 531672a..ee4888d 100644
--- a/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/src/com/android/launcher3/SavedWallpaperImages.java
@@ -79,6 +79,10 @@
         public boolean isSelectable() {
             return true;
         }
+        @Override
+        public boolean isNamelessWallpaper() {
+            return true;
+        }
     }
 
     public SavedWallpaperImages(Activity context) {
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index b951100..fcd6f19 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -103,7 +103,9 @@
 
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
-            measureChild(child);
+            if (child.getVisibility() != GONE) {
+                measureChild(child);
+            }
         }
     }
 
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index 78c8964..fe09a55 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -102,8 +102,6 @@
                         cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone);
                     }
                 });
-        TranslucentDecor transparentDecor = new TranslucentDecor(findViewById(R.id.wallpaper_root));
-        transparentDecor.requestTranslucentDecor(true);
     }
 
     public boolean enableRotation() {
diff --git a/src/com/android/launcher3/WallpaperPickerActivity.java b/src/com/android/launcher3/WallpaperPickerActivity.java
index 82c9977..9d3164b 100644
--- a/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -92,10 +92,20 @@
     private WallpaperInfo mLiveWallpaperInfoOnPickerLaunch;
 
     public static abstract class WallpaperTileInfo {
+        protected View mView;
+        public void setView(View v) {
+            mView = v;
+        }
         public void onClick(WallpaperPickerActivity a) {}
         public void onSave(WallpaperPickerActivity a) {}
         public void onDelete(WallpaperPickerActivity a) {}
         public boolean isSelectable() { return false; }
+        public boolean isNamelessWallpaper() { return false; }
+        public void onIndexUpdated(CharSequence label) {
+            if (isNamelessWallpaper()) {
+                mView.setContentDescription(label);
+            }
+        }
     }
 
     public static class PickImageInfo extends WallpaperTileInfo {
@@ -136,6 +146,10 @@
         public boolean isSelectable() {
             return true;
         }
+        @Override
+        public boolean isNamelessWallpaper() {
+            return true;
+        }
     }
 
     public static class ResourceWallpaperInfo extends WallpaperTileInfo {
@@ -171,6 +185,10 @@
         public boolean isSelectable() {
             return true;
         }
+        @Override
+        public boolean isNamelessWallpaper() {
+            return true;
+        }
     }
 
     public void setWallpaperStripYOffset(float offset) {
@@ -181,8 +199,6 @@
     protected void init() {
         setContentView(R.layout.wallpaper_picker);
         final WallpaperRootView root = (WallpaperRootView) findViewById(R.id.wallpaper_root);
-        TranslucentDecor transparentDecor = new TranslucentDecor(root);
-        transparentDecor.requestTranslucentDecor(true);
 
         mCropView = (CropView) findViewById(R.id.cropView);
         mWallpaperStrip = findViewById(R.id.wallpaper_strip);
@@ -282,6 +298,7 @@
                 liveWallpapersView.removeAllViews();
                 populateWallpapersFromAdapter(liveWallpapersView, a, false, false);
                 initializeScrollForRtl();
+                updateTileIndices();
             }
         });
 
@@ -294,16 +311,16 @@
 
         // Add a tile for the Gallery
         LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list);
-        FrameLayout galleryThumbnail = (FrameLayout) getLayoutInflater().
+        FrameLayout pickImageTile = (FrameLayout) getLayoutInflater().
                 inflate(R.layout.wallpaper_picker_image_picker_item, masterWallpaperList, false);
-        setWallpaperItemPaddingToZero(galleryThumbnail);
-        masterWallpaperList.addView(galleryThumbnail, 0);
+        setWallpaperItemPaddingToZero(pickImageTile);
+        masterWallpaperList.addView(pickImageTile, 0);
 
         // Make its background the last photo taken on external storage
         Bitmap lastPhoto = getThumbnailOfLastPhoto();
         if (lastPhoto != null) {
             ImageView galleryThumbnailBg =
-                    (ImageView) galleryThumbnail.findViewById(R.id.wallpaper_image);
+                    (ImageView) pickImageTile.findViewById(R.id.wallpaper_image);
             galleryThumbnailBg.setImageBitmap(getThumbnailOfLastPhoto());
             int colorOverlay = getResources().getColor(R.color.wallpaper_picker_translucent_gray);
             galleryThumbnailBg.setColorFilter(colorOverlay, PorterDuff.Mode.SRC_ATOP);
@@ -311,8 +328,12 @@
         }
 
         PickImageInfo pickImageInfo = new PickImageInfo();
-        galleryThumbnail.setTag(pickImageInfo);
-        galleryThumbnail.setOnClickListener(mThumbnailOnClickListener);
+        pickImageTile.setTag(pickImageInfo);
+        pickImageInfo.setView(pickImageTile);
+        pickImageTile.setOnClickListener(mThumbnailOnClickListener);
+        pickImageInfo.setView(pickImageTile);
+
+        updateTileIndices();
 
         // Update the scroll for RTL
         initializeScrollForRtl();
@@ -396,6 +417,7 @@
                     for (View v : viewsToRemove) {
                         mWallpapersView.removeView(v);
                     }
+                    updateTileIndices();
                     mode.finish(); // Action picked, so close the CAB
                     return true;
                 } else {
@@ -479,7 +501,9 @@
         for (int i = 0; i < adapter.getCount(); i++) {
             FrameLayout thumbnail = (FrameLayout) adapter.getView(i, null, parent);
             parent.addView(thumbnail, i);
-            thumbnail.setTag(adapter.getItem(i));
+            WallpaperTileInfo info = (WallpaperTileInfo) adapter.getItem(i);
+            thumbnail.setTag(info);
+            info.setView(thumbnail);
             if (addLongPressHandler) {
                 addLongPressHandler(thumbnail);
             }
@@ -490,6 +514,48 @@
         }
     }
 
+    private void updateTileIndices() {
+        LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list);
+        final int childCount = masterWallpaperList.getChildCount();
+        ArrayList<WallpaperTileInfo> tiles = new ArrayList<WallpaperTileInfo>();
+        final Resources res = getResources();
+
+        // Do two passes; the first pass gets the total number of tiles
+        int numTiles = 0;
+        for (int passNum = 0; passNum < 2; passNum++) {
+            int tileIndex = 0;
+            for (int i = 0; i < childCount; i++) {
+                View child = masterWallpaperList.getChildAt(i);
+                LinearLayout subList;
+
+                int subListStart;
+                int subListEnd;
+                if (child.getTag() instanceof WallpaperTileInfo) {
+                    subList = masterWallpaperList;
+                    subListStart = i;
+                    subListEnd = i + 1;
+                } else { // if (child instanceof LinearLayout) {
+                    subList = (LinearLayout) child;
+                    subListStart = 0;
+                    subListEnd = subList.getChildCount();
+                }
+
+                for (int j = subListStart; j < subListEnd; j++) {
+                    WallpaperTileInfo info = (WallpaperTileInfo) subList.getChildAt(j).getTag();
+                    if (info.isNamelessWallpaper()) {
+                        if (passNum == 0) {
+                            numTiles++;
+                        } else {
+                            CharSequence label = res.getString(
+                                    R.string.wallpaper_accessibility_name, ++tileIndex, numTiles);
+                            info.onIndexUpdated(label);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private static Point getDefaultThumbnailSize(Resources res) {
         return new Point(res.getDimensionPixelSize(R.dimen.wallpaperThumbnailWidth),
                 res.getDimensionPixelSize(R.dimen.wallpaperThumbnailHeight));
@@ -545,9 +611,11 @@
             Log.e(TAG, "Error loading thumbnail for uri=" + uri);
         }
         mWallpapersView.addView(pickedImageThumbnail, 0);
+        updateTileIndices();
 
         UriWallpaperInfo info = new UriWallpaperInfo(uri);
         pickedImageThumbnail.setTag(info);
+        info.setView(pickedImageThumbnail);
         pickedImageThumbnail.setOnClickListener(mThumbnailOnClickListener);
         mThumbnailOnClickListener.onClick(pickedImageThumbnail);
     }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a81ada8..b9552ea 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -459,7 +459,8 @@
     protected boolean shouldDrawChild(View child) {
         final CellLayout cl = (CellLayout) child;
         return super.shouldDrawChild(child) &&
-            (cl.getShortcutsAndWidgets().getAlpha() > 0 ||
+            (mIsSwitchingState ||
+             cl.getShortcutsAndWidgets().getAlpha() > 0 ||
              cl.getBackgroundAlpha() > 0);
     }
 
@@ -1920,7 +1921,8 @@
         float finalSearchBarAlpha = !stateIsNormal ? 0f : 1f;
         float finalWorkspaceTranslationY = stateIsOverview ? getOverviewModeTranslationY() : 0;
 
-        boolean zoomIn = true;
+        boolean workspaceToAllApps = (oldStateIsNormal && stateIsSmall);
+        boolean allAppsToWorkspace = (oldStateIsSmall && stateIsNormal);
         mNewScale = 1.0f;
 
         if (oldStateIsOverview) {
@@ -1937,19 +1939,32 @@
             } else if (stateIsSmall){
                 mNewScale = mOverviewModeShrinkFactor - 0.3f;
             }
-            if (oldStateIsNormal && stateIsSmall) {
-                zoomIn = false;
+            if (workspaceToAllApps) {
                 updateChildrenLayersEnabled(false);
             }
         }
-        final int duration = zoomIn ?
+
+        final int duration = workspaceToAllApps ?
                 getResources().getInteger(R.integer.config_workspaceUnshrinkTime) :
                 getResources().getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
         for (int i = 0; i < getChildCount(); i++) {
             final CellLayout cl = (CellLayout) getChildAt(i);
-            float finalAlpha = (!mWorkspaceFadeInAdjacentScreens ||
-                    (i == mCurrentPage)) && !stateIsSmall ? 1f : 0f;
+            boolean isCurrentPage = (i == getNextPage());
             float initialAlpha = cl.getShortcutsAndWidgets().getAlpha();
+            float finalAlpha = stateIsSmall ? 0f : 1f;
+
+            // If we are animating to/from the small state, then hide the side pages and fade the
+            // current page in
+            if (!mIsSwitchingState) {
+                if (workspaceToAllApps || allAppsToWorkspace) {
+                    if (allAppsToWorkspace && isCurrentPage) {
+                        initialAlpha = 0f;
+                    } else if (!isCurrentPage) {
+                        initialAlpha = finalAlpha = 0f;
+                    }
+                    cl.setShortcutAndWidgetAlpha(initialAlpha);
+                }
+            }
 
             mOldAlphas[i] = initialAlpha;
             mNewAlphas[i] = finalAlpha;
@@ -2109,6 +2124,10 @@
 
     private void onTransitionPrepare() {
         mIsSwitchingState = true;
+
+        // Invalidate here to ensure that the pages are rendered during the state change transition.
+        invalidate();
+
         updateChildrenLayersEnabled(false);
         hideCustomContentIfNecessary();
     }