Fix 3061600: Allow scrolling to last few items in CarouselView.

This fixes a bug where the last few items cannot be scrolled to.
The code now follows visibleDetailCount to allow scrolling all
cards into the "visible area" for inspection and selection.

Change-Id: I0fded18f0f7ac2828385164b287fec2f522dc3a0
Fixes: Music2, Books, Recents.
diff --git a/carousel/java/com/android/ex/carousel/carousel.rs b/carousel/java/com/android/ex/carousel/carousel.rs
index f11aed3..670c3a2 100644
--- a/carousel/java/com/android/ex/carousel/carousel.rs
+++ b/carousel/java/com/android/ex/carousel/carousel.rs
@@ -269,6 +269,12 @@
     return startAngle + 2.0f * M_PI * p / slotCount;
 }
 
+// Returns total angle for given number of cards
+static float wedgeAngle(float cards)
+{
+    return cards * 2.0f * M_PI / slotCount;
+}
+
 // Return the lowest slot number for a given angular position.
 static int cardIndex(float angle)
 {
@@ -970,20 +976,13 @@
     }
     lastTime = currentTime;
 
-    // TODO: Add animation to smoothly move back to slots. Currently snaps to location.
-    if (cardCount <= visibleSlotCount) {
-        // TODO: this aligns the cards to the first slot (theta = startAngle) when there aren't
-        // enough visible cards. It should be generalized to allow alignment to front,
-        // middle or back of the stack.
-        if (cardPosition(0) != slotPosition(0)) {
-            bias = 0.0f;
-        }
-    } else {
-        if (cardPosition(cardCount) < 0.0f) {
-            bias = -slotPosition(cardCount);
-        } else if (cardPosition(0) > slotPosition(0)) {
-            bias = 0.0f;
-        }
+    const float firstBias = wedgeAngle(0.0f);
+    const float lastBias = -max(0.0f, wedgeAngle(cardCount - visibleDetailCount));
+
+    if (bias > firstBias) {
+        bias = firstBias;
+    } else if (bias < lastBias) {
+        bias = lastBias;
     }
 
     return animating;
diff --git a/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java b/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java
index ddd76f5..cf37018 100644
--- a/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java
+++ b/carousel/test/src/com/android/carouseltest/CarouselTestActivity.java
@@ -17,15 +17,11 @@
 package com.android.carouseltest;
 
 import com.android.carouseltest.MyCarouselView;
-import com.android.carouseltest.TaskSwitcherActivity.ActivityDescription;
 import com.android.ex.carousel.CarouselView;
 import com.android.ex.carousel.CarouselViewHelper;
-import com.android.ex.carousel.CarouselViewHelper.DetailTextureParameters;
 
 import android.app.Activity;
-import android.content.ActivityNotFoundException;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -35,7 +31,6 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.util.Log;
-import android.view.WindowManager;
 
 public class CarouselTestActivity extends Activity {
     private static final String TAG = "CarouselTestActivity";
@@ -48,6 +43,7 @@
     protected static final boolean DBG = false;
     private static final int DETAIL_TEXTURE_WIDTH = 200;
     private static final int DETAIL_TEXTURE_HEIGHT = 80;
+    private static final int VISIBLE_DETAIL_COUNT = 3;
     private CarouselView mView;
     private Paint mPaint = new Paint();
     private CarouselViewHelper mHelper;
@@ -130,6 +126,7 @@
         mView.setBackgroundColor(0.25f, 0.25f, 0.5f, 0.5f);
         mView.setRezInCardCount(3.0f);
         mView.setFadeInDuration(250);
+        mView.setVisibleDetails(VISIBLE_DETAIL_COUNT);
 
         mGlossyOverlay = BitmapFactory.decodeResource(res, R.drawable.glossy_overlay);