Merge "[multi-part] Eliminate 1k selection limit"
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 26ab00ff..953d705 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -104,6 +104,7 @@
 
 hwui_test_common_src_files := \
     $(call all-cpp-files-under, tests/common/scenes) \
+    tests/common/TestListViewSceneBase.cpp \
     tests/common/TestContext.cpp \
     tests/common/TestScene.cpp \
     tests/common/TestUtils.cpp
diff --git a/libs/hwui/tests/common/TestListViewSceneBase.cpp b/libs/hwui/tests/common/TestListViewSceneBase.cpp
new file mode 100644
index 0000000..847a6ff
--- /dev/null
+++ b/libs/hwui/tests/common/TestListViewSceneBase.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "TestListViewSceneBase.h"
+
+#include "TestContext.h"
+#include "TestUtils.h"
+
+#include <utils/Color.h>
+
+namespace android {
+namespace uirenderer {
+namespace test {
+
+void TestListViewSceneBase::createContent(int width, int height, TestCanvas& canvas) {
+    srand(0);
+    mItemHeight = dp(60);
+    mItemSpacing = dp(16);
+    mItemWidth = std::min((height - mItemSpacing * 2), (int)dp(300));
+    mItemLeft = (width - mItemWidth) / 2;
+    int heightWithSpacing = mItemHeight + mItemSpacing;
+    for (int y = 0; y < height + (heightWithSpacing - 1); y += heightWithSpacing) {
+        int id = mListItems.size();
+        auto setup = std::bind(&TestListViewSceneBase::createListItem, this, std::placeholders::_1,
+                std::placeholders::_2, id, mItemWidth, mItemHeight);
+        auto node = TestUtils::createNode(mItemLeft, y, mItemLeft + mItemWidth,
+                y + mItemHeight, setup);
+        mListItems.push_back(node);
+    }
+    mListView = TestUtils::createNode(0, 0, width, height,
+            [this](RenderProperties& props, TestCanvas& canvas) {
+        for (size_t ci = 0; ci < mListItems.size(); ci++) {
+            canvas.drawRenderNode(mListItems[ci].get());
+        }
+    });
+
+    canvas.drawColor(Color::Grey_500, SkXfermode::kSrcOver_Mode);
+    canvas.drawRenderNode(mListView.get());
+}
+
+void TestListViewSceneBase::doFrame(int frameNr) {
+    int scrollPx = dp(frameNr) * 3;
+    int itemIndexOffset = scrollPx / (mItemSpacing + mItemHeight);
+    int pxOffset = -(scrollPx % (mItemSpacing + mItemHeight));
+
+    TestCanvas canvas(
+            mListView->stagingProperties().getWidth(),
+            mListView->stagingProperties().getHeight());
+    for (size_t ci = 0; ci < mListItems.size(); ci++) {
+        // update item position
+        auto listItem = mListItems[(ci + itemIndexOffset) % mListItems.size()];
+        int top = ((int)ci) * (mItemSpacing + mItemHeight) + pxOffset;
+        listItem->mutateStagingProperties().setLeftTopRightBottom(
+                mItemLeft, top, mItemLeft + mItemWidth, top + mItemHeight);
+        listItem->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
+
+        // draw it to parent DisplayList
+        canvas.drawRenderNode(mListItems[ci].get());
+    }
+    mListView->setStagingDisplayList(canvas.finishRecording(), nullptr);
+}
+
+} // namespace test
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/tests/common/TestListViewSceneBase.h b/libs/hwui/tests/common/TestListViewSceneBase.h
new file mode 100644
index 0000000..8ffe992
--- /dev/null
+++ b/libs/hwui/tests/common/TestListViewSceneBase.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+#pragma once
+
+#include "TestScene.h"
+#include <RenderNode.h>
+#include <RenderProperties.h>
+
+namespace android {
+namespace uirenderer {
+namespace test {
+
+class TestListViewSceneBase : public TestScene {
+public:
+    virtual void createListItem(RenderProperties& props, TestCanvas& canvas, int id,
+            int itemWidth, int itemHeight) = 0;
+private:
+    int mItemHeight;
+    int mItemSpacing;
+    int mItemWidth;
+    int mItemLeft;
+    sp<RenderNode> mListView;
+    std::vector< sp<RenderNode> > mListItems;
+
+    void createContent(int width, int height, TestCanvas& canvas) override;
+    void doFrame(int frameNr) override;
+};
+
+} // namespace test
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp b/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp
new file mode 100644
index 0000000..ba6074f
--- /dev/null
+++ b/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "TestSceneBase.h"
+#include "tests/common/TestListViewSceneBase.h"
+
+#include <SkGradientShader.h>
+
+class ListOfFadedTextAnimation;
+
+static TestScene::Registrar _ListOfFadedTextAnimation(TestScene::Info{
+    "fadingedges",
+    "A mock ListView of scrolling text with faded edge. Doesn't re-bind/re-record views"
+    "as they are recycled, so won't upload much content (either glyphs, or bitmaps).",
+    TestScene::simpleCreateScene<ListOfFadedTextAnimation>
+});
+
+class ListOfFadedTextAnimation : public TestListViewSceneBase {
+    void createListItem(RenderProperties& props, TestCanvas& canvas, int id,
+            int itemWidth, int itemHeight)  override {
+        canvas.drawColor(Color::White, SkXfermode::kSrcOver_Mode);
+        int length = dp(100);
+        canvas.saveLayer(0, 0, length, itemHeight, nullptr, SaveFlags::HasAlphaLayer);
+        SkPaint textPaint;
+        textPaint.setTextSize(dp(20));
+        textPaint.setAntiAlias(true);
+        TestUtils::drawUtf8ToCanvas(&canvas, "not that long long text", textPaint, dp(10), dp(30));
+
+        SkPoint pts[2];
+        pts[0].set(0, 0);
+        pts[1].set(0, 1);
+
+        SkColor colors[2] = {Color::Black, Color::Transparent};
+        SkAutoTUnref<SkShader> s(SkGradientShader::CreateLinear(pts, colors, NULL, 2,
+                SkShader::kClamp_TileMode));
+
+        SkMatrix matrix;
+        matrix.setScale(1, length);
+        matrix.postRotate(-90);
+        SkPaint fadingPaint;
+        fadingPaint.setShader(s->newWithLocalMatrix(matrix))->unref();
+        SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstOut_Mode);
+        fadingPaint.setXfermode(mode);
+        canvas.drawRect(0, 0, length, itemHeight, fadingPaint);
+        canvas.restore();
+    }
+};
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index 8de28fe..a614044 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -15,7 +15,7 @@
  */
 
 #include "TestSceneBase.h"
-#include "utils/Color.h"
+#include "tests/common/TestListViewSceneBase.h"
 
 #include <cstdio>
 
@@ -28,58 +28,8 @@
     TestScene::simpleCreateScene<ListViewAnimation>
 });
 
-class ListViewAnimation : public TestScene {
-public:
-    int cardHeight;
-    int cardSpacing;
-    int cardWidth;
-    int cardLeft;
-    sp<RenderNode> listView;
-    std::vector< sp<RenderNode> > cards;
-    void createContent(int width, int height, TestCanvas& canvas) override {
-        srand(0);
-        cardHeight = dp(60);
-        cardSpacing = dp(16);
-        cardWidth = std::min((height - cardSpacing * 2), (int)dp(300));
-        cardLeft = (width - cardWidth) / 2;
-
-        for (int y = 0; y < height + (cardHeight + cardSpacing - 1); y += (cardHeight + cardSpacing)) {
-            cards.push_back(createCard(cards.size(), y));
-        }
-        listView = TestUtils::createNode(0, 0, width, height,
-                [this](RenderProperties& props, TestCanvas& canvas) {
-            for (size_t ci = 0; ci < cards.size(); ci++) {
-                canvas.drawRenderNode(cards[ci].get());
-            }
-        });
-
-        canvas.drawColor(Color::Grey_500, SkXfermode::kSrcOver_Mode);
-        canvas.drawRenderNode(listView.get());
-    }
-
-    void doFrame(int frameNr) override {
-        int scrollPx = dp(frameNr) * 3;
-        int cardIndexOffset = scrollPx / (cardSpacing + cardHeight);
-        int pxOffset = -(scrollPx % (cardSpacing + cardHeight));
-
-        TestCanvas canvas(
-                listView->stagingProperties().getWidth(),
-                listView->stagingProperties().getHeight());
-        for (size_t ci = 0; ci < cards.size(); ci++) {
-            // update card position
-            auto card = cards[(ci + cardIndexOffset) % cards.size()];
-            int top = ((int)ci) * (cardSpacing + cardHeight) + pxOffset;
-            card->mutateStagingProperties().setLeftTopRightBottom(
-                    cardLeft, top, cardLeft + cardWidth, top + cardHeight);
-            card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y);
-
-            // draw it to parent DisplayList
-            canvas.drawRenderNode(cards[ci].get());
-        }
-        listView->setStagingDisplayList(canvas.finishRecording(), nullptr);
-    }
-private:
-    SkBitmap createRandomCharIcon() {
+class ListViewAnimation : public TestListViewSceneBase {
+    SkBitmap createRandomCharIcon(int cardHeight) {
         int size = cardHeight - (dp(10) * 2);
         SkBitmap bitmap = TestUtils::createSkBitmap(size, size);
         SkCanvas canvas(bitmap);
@@ -120,34 +70,31 @@
         return bitmap;
     }
 
-    sp<RenderNode> createCard(int cardId, int top) {
-        return TestUtils::createNode(cardLeft, top, cardLeft + cardWidth, top + cardHeight,
-                [this, cardId](RenderProperties& props, TestCanvas& canvas) {
-            static SkBitmap filledBox = createBoxBitmap(true);
-            static SkBitmap strokedBox = createBoxBitmap(false);
+    void createListItem(RenderProperties& props, TestCanvas& canvas, int cardId,
+            int itemWidth, int itemHeight) override {
+        static SkBitmap filledBox = createBoxBitmap(true);
+        static SkBitmap strokedBox = createBoxBitmap(false);
+        // TODO: switch to using round rect clipping, once merging correctly handles that
+        SkPaint roundRectPaint;
+        roundRectPaint.setAntiAlias(true);
+        roundRectPaint.setColor(Color::White);
+        canvas.drawRoundRect(0, 0, itemWidth, itemHeight, dp(6), dp(6), roundRectPaint);
 
-            // TODO: switch to using round rect clipping, once merging correctly handles that
-            SkPaint roundRectPaint;
-            roundRectPaint.setAntiAlias(true);
-            roundRectPaint.setColor(Color::White);
-            canvas.drawRoundRect(0, 0, cardWidth, cardHeight, dp(6), dp(6), roundRectPaint);
+        SkPaint textPaint;
+        textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        textPaint.setColor(rand() % 2 ? Color::Black : Color::Grey_500);
+        textPaint.setTextSize(dp(20));
+        textPaint.setAntiAlias(true);
+        char buf[256];
+        snprintf(buf, sizeof(buf), "This card is #%d", cardId);
+        TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, itemHeight, dp(25));
+        textPaint.setTextSize(dp(15));
+        TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint,
+                itemHeight, dp(45));
 
-            SkPaint textPaint;
-            textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
-            textPaint.setColor(rand() % 2 ? Color::Black : Color::Grey_500);
-            textPaint.setTextSize(dp(20));
-            textPaint.setAntiAlias(true);
-            char buf[256];
-            snprintf(buf, sizeof(buf), "This card is #%d", cardId);
-            TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, cardHeight, dp(25));
-            textPaint.setTextSize(dp(15));
-            TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint,
-                    cardHeight, dp(45));
+        canvas.drawBitmap(createRandomCharIcon(itemHeight), dp(10), dp(10), nullptr);
 
-            canvas.drawBitmap(createRandomCharIcon(), dp(10), dp(10), nullptr);
-
-            const SkBitmap& boxBitmap = rand() % 2 ? filledBox : strokedBox;
-            canvas.drawBitmap(boxBitmap, cardWidth - dp(10) - boxBitmap.width(), dp(10), nullptr);
-        });
+        const SkBitmap& boxBitmap = rand() % 2 ? filledBox : strokedBox;
+        canvas.drawBitmap(boxBitmap, itemWidth - dp(10) - boxBitmap.width(), dp(10), nullptr);
     }
 };
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java
index 0b86894..ffaa16d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsMenuManager.java
@@ -66,12 +66,12 @@
 
     @Override
     void updateSettings(MenuItem settings, DirectoryDetails directoryDetails) {
-        assert(!settings.isVisible());
+        //assert(!settings.isVisible());
     }
 
     @Override
     void updateNewWindow(MenuItem newWindow, DirectoryDetails directoryDetails) {
-        assert(!newWindow.isVisible());
+        //assert(!newWindow.isVisible());
     }
 
     @Override
@@ -108,11 +108,11 @@
 
     @Override
     void updateMoveTo(MenuItem moveTo, SelectionDetails selectionDetails) {
-        assert(!moveTo.isVisible());
+        //assert(!moveTo.isVisible());
     }
 
     @Override
     void updateCopyTo(MenuItem copyTo, SelectionDetails selectionDetails) {
-        assert(!copyTo.isVisible());
+        //assert(!copyTo.isVisible());
     }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java b/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
index 4b27a7e..c639f1a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesMenuManager.java
@@ -37,13 +37,13 @@
 
     @Override
     void updateModePicker(MenuItem grid, MenuItem list, DirectoryDetails directoryDetails) {
-        assert(!grid.isVisible());
-        assert(list.isVisible());
+        //assert(!grid.isVisible());
+        //assert(list.isVisible());
     }
 
     @Override
     void updateFileSize(MenuItem fileSize, DirectoryDetails directoryDetails) {
-        assert(fileSize.isVisible());
+        //assert(fileSize.isVisible());
     }
 
     @Override