Merge "Verifying that new applications are added and fixing issue with new items getting wrong ids." into jb-ub-gel-agar
diff --git a/res/drawable-hdpi/now_page.png b/res/drawable-hdpi/now_page.png
new file mode 100644
index 0000000..9eef50c
--- /dev/null
+++ b/res/drawable-hdpi/now_page.png
Binary files differ
diff --git a/res/drawable-mdpi/now_page.png b/res/drawable-mdpi/now_page.png
new file mode 100644
index 0000000..cc4005d
--- /dev/null
+++ b/res/drawable-mdpi/now_page.png
Binary files differ
diff --git a/res/drawable-xhdpi/now_page.png b/res/drawable-xhdpi/now_page.png
new file mode 100644
index 0000000..e1da91c
--- /dev/null
+++ b/res/drawable-xhdpi/now_page.png
Binary files differ
diff --git a/res/layout/now_page_indicator_marker.xml b/res/layout/now_page_indicator_marker.xml
new file mode 100644
index 0000000..7d05627
--- /dev/null
+++ b/res/layout/now_page_indicator_marker.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<com.android.launcher3.PageIndicatorMarker
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <ImageView
+        android:id="@+id/inactive"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/now_page"
+        />
+    <ImageView
+        android:id="@+id/active"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/now_page"
+        android:alpha="0"
+        />
+</com.android.launcher3.PageIndicatorMarker>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index ac41a2b..86bc1b0 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -3231,6 +3231,11 @@
         public boolean isLockedToGrid = true;
 
         /**
+         * Indicates that this item should use the full extents of its parent.
+         */
+        public boolean isFullscreen = false;
+
+        /**
          * Indicates whether this item can be reordered. Always true except in the case of the
          * the AllApps button.
          */
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index a591433..1acaf3e 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -21,6 +21,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
+import android.widget.ScrollView;
 import android.widget.TabHost;
 import android.widget.TabWidget;
 
@@ -817,7 +818,8 @@
     static boolean handleFolderKeyEvent(View v, int keyCode, KeyEvent e) {
         ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
         final CellLayout layout = (CellLayout) parent.getParent();
-        final Folder folder = (Folder) layout.getParent();
+        final ScrollView scrollView = (ScrollView) layout.getParent();
+        final Folder folder = (Folder) scrollView.getParent();
         View title = folder.mFolderName;
 
         final int action = e.getAction();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 65845b4..853bd8f 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -838,9 +838,44 @@
     protected void onFinishBindingItems() {
     }
 
+    QSBScroller mQsbScroller = new QSBScroller() {
+        int scrollY = 0;
+
+        @Override
+        public void setScrollY(int scroll) {
+            scrollY = scroll;
+
+            if (mWorkspace.isOnOrMovingToCustomContent()) {
+                mSearchDropTargetBar.setTranslationY(- scrollY);
+            }
+        }
+    };
+
+    public void resetQSBScroll() {
+        mSearchDropTargetBar.animate().translationY(0).start();
+    }
+
+    public interface CustomContentCallbacks {
+        // Custom content is completely shown
+        public void onShow();
+
+        // Custom content is completely hidden
+        public void onHide();
+    }
+
+    public interface QSBScroller {
+        public void setScrollY(int scrollY);
+    }
+
     // Add a fullscreen unpadded view to the workspace to the left all other screens.
-    public void addCustomContentToLeft(View customContent) {
-        mWorkspace.addCustomContentToLeft(customContent);
+    public QSBScroller addCustomContentToLeft(View customContent) {
+        return addCustomContentToLeft(customContent, null);
+    }
+
+    public QSBScroller addCustomContentToLeft(View customContent,
+            CustomContentCallbacks callbacks) {
+        mWorkspace.addCustomContentToLeft(customContent, callbacks);
+        return mQsbScroller;
     }
 
     // The custom content needs to offset its content to account for the QSB
@@ -955,7 +990,7 @@
 
         int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
         if (currentScreen > -1) {
-            mWorkspace.setCurrentPage(currentScreen);
+            mWorkspace.setRestorePage(currentScreen);
         }
 
         final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index dd130d2..b231e3a 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1754,7 +1754,9 @@
                         }
                     }
                 } finally {
-                    c.close();
+                    if (c != null) {
+                        c.close();
+                    }
                 }
 
                 if (itemsToRemove.size() > 0) {
diff --git a/src/com/android/launcher3/PageIndicator.java b/src/com/android/launcher3/PageIndicator.java
index d7778fb..ce98145 100644
--- a/src/com/android/launcher3/PageIndicator.java
+++ b/src/com/android/launcher3/PageIndicator.java
@@ -161,18 +161,17 @@
         mWindowRange[1] = windowEnd;
     }
 
-    void addMarker(int index) {
+    void addMarker(int index, int layoutId) {
         index = Math.max(0, Math.min(index, mMarkers.size()));
 
-        int mLayoutId = R.layout.page_indicator_marker;
         PageIndicatorMarker marker =
-            (PageIndicatorMarker) mLayoutInflater.inflate(mLayoutId, this, false);
+            (PageIndicatorMarker) mLayoutInflater.inflate(layoutId, this, false);
         mMarkers.add(index, marker);
         offsetWindowCenterTo(mActiveMarkerIndex, true);
     }
-    void addMarkers(int count) {
-        for (int i = 0; i < count; ++i) {
-            addMarker(Integer.MAX_VALUE);
+    void addMarkers(ArrayList<Integer> layoutIds) {
+        for (int i = 0; i < layoutIds.size(); ++i) {
+            addMarker(Integer.MAX_VALUE, layoutIds.get(i));
         }
     }
 
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index d53fd75..bb596a7 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -104,6 +104,7 @@
     protected boolean mFirstLayout = true;
 
     protected int mCurrentPage;
+    protected int mRestorePage = -1;
     protected int mChildCountOnLastLayout;
 
     protected int mNextPage = INVALID_PAGE;
@@ -326,7 +327,12 @@
         if (mPageIndicator == null && mPageIndicatorViewId > -1) {
             mPageIndicator = (PageIndicator) parent.findViewById(mPageIndicatorViewId);
             mPageIndicator.removeAllMarkers();
-            mPageIndicator.addMarkers(getChildCount());
+
+            ArrayList<Integer> markers = new ArrayList<Integer>();
+            for (int i = 0; i < getChildCount(); ++i) {
+                markers.add(getPageIndicatorMarker(i));
+            }
+            mPageIndicator.addMarkers(markers);
         }
     }
 
@@ -403,6 +409,9 @@
     PageIndicator getPageIndicator() {
         return mPageIndicator;
     }
+    protected int getPageIndicatorMarker(int pageIndex) {
+        return R.layout.page_indicator_marker;
+    }
 
     public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
         mPageSwitchListener = pageSwitchListener;
@@ -506,6 +515,14 @@
         invalidate();
     }
 
+    /**
+     * The restore page will be set in place of the current page at the next (likely first)
+     * layout.
+     */
+    void setRestorePage(int restorePage) {
+        mRestorePage = restorePage;
+    }
+
     protected void notifyPageSwitchListener() {
         if (mPageSwitchListener != null) {
             mPageSwitchListener.onPageSwitch(getPageAt(mCurrentPage), mCurrentPage);
@@ -824,6 +841,7 @@
         }
 
         for (int i = startIndex; i != endIndex; i += delta) {
+
             final View child = getPageAt(i);
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
             int childTop;
@@ -847,10 +865,13 @@
 
                 // We assume the left and right padding are equal, and hence center the pages
                 // horizontally
-                int scrollOffset = false ? 0 : (getViewportWidth() - childWidth) / 2;
+                int scrollOffset = (getViewportWidth() - childWidth) / 2;
                 mPageScrolls[i] = childLeft - scrollOffset - offsetX;
 
-                childLeft += childWidth + mPageSpacing;
+                if (i != endIndex - delta) {
+                    int nextScrollOffset = (getViewportWidth() - getChildWidth(i + delta)) / 2;
+                    childLeft += childWidth + nextScrollOffset;
+                }
             }
         }
 
@@ -870,7 +891,12 @@
 
         if (mScroller.isFinished() && mChildCountOnLastLayout != getChildCount() &&
                 !mDeferringForDelete) {
-            setCurrentPage(getNextPage());
+            if (mRestorePage > -1) {
+                setCurrentPage(mRestorePage);
+                mRestorePage = -1;
+            } else {
+                setCurrentPage(getNextPage());
+            }
         }
         mChildCountOnLastLayout = getChildCount();
     }
@@ -896,7 +922,8 @@
         // Update the page indicator, we don't update the page indicator as we
         // add/remove pages
         if (mPageIndicator != null && !isReordering(false)) {
-            mPageIndicator.addMarker(indexOfChild(child));
+            int pageIndex = indexOfChild(child);
+            mPageIndicator.addMarker(pageIndex, getPageIndicatorMarker(pageIndex));
         }
 
         // This ensures that when children are added, they get the correct transforms / alphas
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 18b9399..64a87ef 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -92,13 +92,15 @@
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int count = getChildCount();
+
+        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);
+        setMeasuredDimension(widthSpecSize, heightSpecSize);
+
         for (int i = 0; i < count; i++) {
             View child = getChildAt(i);
             measureChild(child);
         }
-        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
-        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);
-        setMeasuredDimension(widthSpecSize, heightSpecSize);
     }
 
     public void setupLp(CellLayout.LayoutParams lp) {
@@ -115,8 +117,15 @@
         final int cellWidth = mCellWidth;
         final int cellHeight = mCellHeight;
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-
-        lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(), mCountX);
+        if (!lp.isFullscreen) {
+            lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
+                    mCountX);
+        } else {
+            lp.x = 0;
+            lp.y = 0;
+            lp.width = getMeasuredWidth();
+            lp.height = getMeasuredHeight();
+        }
         int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
         int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
                 MeasureSpec.EXACTLY);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4f8f8d1..6627ec1 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -56,6 +56,7 @@
 import android.widget.TextView;
 
 import com.android.launcher3.FolderIcon.FolderRingAnimator;
+import com.android.launcher3.Launcher.CustomContentCallbacks;
 import com.android.launcher3.LauncherSettings.Favorites;
 
 import java.net.URISyntaxException;
@@ -98,8 +99,6 @@
     boolean mDrawBackground = true;
     private float mBackgroundAlpha = 0;
 
-    private float mWallpaperScrollRatio = 1.0f;
-
     private LayoutTransition mLayoutTransition;
     private final WallpaperManager mWallpaperManager;
     private IBinder mWindowToken;
@@ -129,6 +128,9 @@
     static Rect mLandscapeCellLayoutMetrics = null;
     static Rect mPortraitCellLayoutMetrics = null;
 
+    CustomContentCallbacks mCustomContentCallbacks;
+    boolean mCustomContentShowing;
+
     /**
      * The CellLayout that is currently being dragged over
      */
@@ -526,7 +528,7 @@
         return screenId;
     }
 
-    public void addCustomContentToLeft(View customContent) {
+    public void addCustomContentToLeft(View customContent, CustomContentCallbacks callbacks) {
         CellLayout customScreen = (CellLayout)
                 mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
 
@@ -535,23 +537,20 @@
 
         CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, spanX, spanY);
         lp.canReorder  = false;
+        lp.isFullscreen = true;
 
         customScreen.addViewToCellLayout(customContent, 0, 0, lp, true);
 
         Rect p = new Rect();
         AppWidgetHostView.getDefaultPaddingForWidget(mLauncher, mLauncher.getComponentName(), p);
 
-        // For now we force top padding on the entire custom content screen. The intention
-        // is for the hosted content to get this offset and account for it so that upon scrolling
-        // it can use the entire space.
-        customContent.setPadding(p.left, mLauncher.getTopOffsetForCustomContent(),
-                p.right, p.bottom);
-
         mWorkspaceScreens.put(CUSTOM_CONTENT_SCREEN_ID, customScreen);
         mScreenOrder.add(0, CUSTOM_CONTENT_SCREEN_ID);
 
         addFullScreenPage(customScreen);
 
+        mCustomContentCallbacks = callbacks;
+
         // Ensure that the current page and default page are maintained.
         mDefaultPage++;
         setCurrentPage(getCurrentPage() + 1);
@@ -771,6 +770,13 @@
 
     protected void onWindowVisibilityChanged (int visibility) {
         mLauncher.onWindowVisibilityChanged(visibility);
+        if (mCustomContentShowing && mCustomContentCallbacks != null) {
+            if (visibility == View.VISIBLE) {
+                mCustomContentCallbacks.onShow();
+            } else if (visibility == View.GONE) {
+                mCustomContentCallbacks.onHide();
+            }
+        }
     }
 
     @Override
@@ -931,6 +937,19 @@
             stripEmptyScreens();
             mStripScreensOnPageStopMoving = false;
         }
+
+        if (hasCustomContent() && getNextPage() == 0 && !mCustomContentShowing) {
+            mCustomContentShowing = true;
+            if (mCustomContentCallbacks != null) {
+                mCustomContentCallbacks.onShow();
+            }
+        } else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
+            mCustomContentShowing = false;
+            if (mCustomContentCallbacks != null) {
+                mCustomContentCallbacks.onHide();
+                mLauncher.resetQSBScroll();
+            }
+        }
     }
 
     @Override
@@ -966,11 +985,6 @@
         return x * aspectRatio + y;
     }
 
-    // The range of scroll values for Workspace
-    private int getScrollRange() {
-        return getChildOffset(getChildCount() - 1) - getChildOffset(0);
-    }
-
     protected void setWallpaperDimension() {
         Point minDims = new Point();
         Point maxDims = new Point();
@@ -995,33 +1009,6 @@
         }.start();
     }
 
-    private float wallpaperOffsetForCurrentScroll() {
-        // Set wallpaper offset steps (1 / (number of screens - 1))
-        mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f);
-
-        int scrollRange = getScrollRange();
-
-        float adjustedScrollX = Math.max(0, Math.min(getScrollX(), mMaxScrollX));
-        adjustedScrollX *= mWallpaperScrollRatio;
-
-        float scrollProgress =
-            adjustedScrollX / (float) scrollRange;
-
-        if (LauncherAppState.getInstance().isScreenLarge() && mIsStaticWallpaper) {
-            // The wallpaper travel width is how far, from left to right, the wallpaper will move
-            // at this orientation. On tablets in portrait mode we don't move all the way to the
-            // edges of the wallpaper, or otherwise the parallax effect would be too strong.
-            int wallpaperTravelWidth = Math.min(mWallpaperTravelWidth, mWallpaperWidth);
-
-            float offsetInDips = wallpaperTravelWidth * scrollProgress +
-                (mWallpaperWidth - wallpaperTravelWidth) / 2; // center it
-            float offset = offsetInDips / (float) mWallpaperWidth;
-            return offset;
-        } else {
-            return scrollProgress;
-        }
-    }
-
     private void syncWallpaperOffsetWithScroll() {
         final boolean enableWallpaperEffects = isHardwareAccelerated();
         if (enableWallpaperEffects) {
@@ -1317,13 +1304,15 @@
         return (mScreenOrder.size() > 0 && mScreenOrder.get(0) == CUSTOM_CONTENT_SCREEN_ID);
     }
 
+    public boolean isOnOrMovingToCustomContent() {
+        return hasCustomContent() && getNextPage() == 0;
+    }
+
     private void updateStateForCustomContent(int screenCenter) {
         if (hasCustomContent()) {
-            CellLayout customContent = getScreenWithId(CUSTOM_CONTENT_SCREEN_ID);
             int index = mScreenOrder.indexOf(CUSTOM_CONTENT_SCREEN_ID);
 
             int scrollDelta = getScrollForPage(index + 1) - getScrollX();
-            float translationX = Math.max(scrollDelta, 0);
 
             float progress = (1.0f * scrollDelta) /
                     (getScrollForPage(index + 1) - getScrollForPage(index));
@@ -1340,6 +1329,7 @@
 
             if (mLauncher.getHotseat() != null) {
                 mLauncher.getHotseat().setTranslationY(transY);
+                mLauncher.getHotseat().setAlpha(1 - progress);
             }
             if (getPageIndicator() != null) {
                 getPageIndicator().setAlpha(1 - progress);
@@ -3721,6 +3711,11 @@
             final int page = getNextPage() +
                        (direction == DragController.SCROLL_LEFT ? -1 : 1);
 
+            // Ensure that we are not dragging over to the custom content screen
+            if (getScreenIdForPageIndex(page) == CUSTOM_CONTENT_SCREEN_ID) {
+                return false;
+            }
+
             // We always want to exit the current layout to ensure parity of enter / exit
             setCurrentDropLayout(null);
 
@@ -4041,6 +4036,14 @@
     }
 
     @Override
+    protected int getPageIndicatorMarker(int pageIndex) {
+        if (getScreenIdForPageIndex(pageIndex) == CUSTOM_CONTENT_SCREEN_ID) {
+            return R.layout.now_page_indicator_marker;
+        }
+        return super.getPageIndicatorMarker(pageIndex);
+    }
+
+    @Override
     public void syncPages() {
     }