OSDN Git Service

3rd party folders not appearing on resume Crash on computing sorted intersections...
authorVenkat Krishnaraj <venkatkrishnaraj@venkat-krishnarajs-macbook-pro.local>
Sat, 5 Dec 2009 02:26:47 +0000 (18:26 -0800)
committerDave Sparks <davidsparks@android.com>
Mon, 7 Dec 2009 17:01:43 +0000 (09:01 -0800)
Please enter the commit message for your changes. Lines starting

src/com/cooliris/cache/CacheService.java
src/com/cooliris/media/ArrayUtils.java
src/com/cooliris/media/DetailMode.java
src/com/cooliris/media/Gallery.java
src/com/cooliris/media/GridInputProcessor.java
src/com/cooliris/media/GridLayer.java
src/com/cooliris/media/LocalDataSource.java
src/com/cooliris/media/MediaFeed.java
src/com/cooliris/media/PicasaDataSource.java

index 68c4ea5..a3bd75c 100644 (file)
@@ -14,12 +14,12 @@ import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Locale;
 import java.util.concurrent.atomic.AtomicReference;
 
 import android.app.IntentService;
-import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -43,7 +43,6 @@ import android.util.Log;
 import com.cooliris.media.DataSource;
 import com.cooliris.media.DiskCache;
 import com.cooliris.media.Gallery;
-import com.cooliris.media.ImageManager;
 import com.cooliris.media.LocalDataSource;
 import com.cooliris.media.LongSparseArray;
 import com.cooliris.media.MediaFeed;
@@ -199,6 +198,12 @@ public final class CacheService extends IntentService {
                        QUEUE_DIRTY_SET = false;
                        restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
                                public void run() {
+                                       try {
+                                               // We sleep for a bit here waiting for the provider database to insert the row(s).
+                                               // This should be unnecessary, and to be fixed in future versions.
+                           Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                    }
                                        Log.i(TAG, "Computing dirty sets.");
                                        long ids[] = computeDirtySets(context);
                                        if (ids != null && observer != null) {
@@ -852,16 +857,6 @@ public final class CacheService extends IntentService {
                return C;
        }
 
-       private static final long toLong(final byte[] data) {
-               // 8 bytes for a long
-               if (data == null || data.length < 8)
-                       return 0;
-               final ByteBuffer bBuffer = ByteBuffer.wrap(data);
-               final LongBuffer lBuffer = bBuffer.asLongBuffer();
-               final int numLongs = lBuffer.capacity();
-               return lBuffer.get(0);
-       }
-
        private static final long[] toLongArray(final byte[] data) {
                final ByteBuffer bBuffer = ByteBuffer.wrap(data);
                final LongBuffer lBuffer = bBuffer.asLongBuffer();
@@ -988,22 +983,20 @@ public final class CacheService extends IntentService {
                cursors[0] = cursorImages;
                cursors[1] = cursorVideos;
                final MergeCursor cursor = new MergeCursor(cursors);
-               long[] retVal = null;
-               int ctr = 0;
+               ArrayList<Long> retVal = new ArrayList<Long>();
                try {
                        if (cursor.moveToFirst()) {
-                               retVal = new long[cursor.getCount()];
                                boolean allDirty = false;
                                do {
                                        long setId = cursor.getLong(0);
                                        if (allDirty) {
-                                               retVal[ctr++] = setId;
+                                               addNoDupe(retVal, setId);
                                        } else {
                                                boolean contains = sAlbumCache.isDataAvailable(setId, 0);
                                                if (!contains) {
                                                        // We need to refresh everything.
                                                        markDirty(context);
-                                                       retVal[ctr++] = setId;
+                                                       addNoDupe(retVal, setId);
                                                        allDirty = true;
                                                }
                                                if (!allDirty) {
@@ -1016,10 +1009,9 @@ public final class CacheService extends IntentService {
                                                        }
                                                        long oldMaxAdded = dataLong[0];
                                                        long oldCount = dataLong[1];
-                                                       Log.i(TAG, "Bucket " + setId + " Old added " + oldMaxAdded + " count " + oldCount + " New added " + maxAdded + " count " + count);
                                                        if (maxAdded > oldMaxAdded || oldCount != count) {
                                                                markDirty(context, setId);
-                                                               retVal[ctr++] = setId;
+                                                               addNoDupe(retVal, setId);
                                                                dataLong[0] = maxAdded;
                                                                dataLong[1] = count;
                                                                sMetaAlbumCache.put(setId, longArrayToByteArray(dataLong));
@@ -1033,11 +1025,21 @@ public final class CacheService extends IntentService {
                }
                sMetaAlbumCache.flush();
                processQueuedDirty(context);
-               long[] retValCompact = new long[ctr];
-               for (int i = 0; i < ctr; ++i) {
-                       retValCompact[i] = retVal[i];
+               int numIds = retVal.size();
+               long retValIds[] = new long[retVal.size()];
+               for (int i = 0; i < numIds; ++i) {
+                       retValIds[i] = retVal.get(i);
+               }
+               return retValIds;
+       }
+       
+       private static final void addNoDupe(ArrayList<Long> array, long value) {
+               int size = array.size();
+               for (int i = 0; i < size; ++i) {
+                       if (array.get(i).longValue() == value)
+                               return;
                }
-               return retValCompact;
+               array.add(value);
        }
 
        private static final void processQueuedDirty(final Context context) {
index 29a4f32..4f7e11e 100644 (file)
@@ -21,6 +21,8 @@ public final class ArrayUtils {
         int firstListSize = firstList.size();
         for (int i = 0; i < firstListSize; ++i) {
             MediaItem firstListItem = firstList.get(i);
+            if (firstListItem == null)
+               continue;
             MediaItem hashItem = (hash != null) ? hash[firstListItem.hashCode() & mask] : null;
             if (hashItem != null && ((hashItem.mId != Shared.INVALID && hashItem.mId == firstListItem.mId) || contains(secondList, firstListItem))) {
                 intersectionList.add(firstListItem);
index cf78a58..10c06c1 100644 (file)
@@ -48,21 +48,21 @@ public final class DetailMode {
             return null;
         }
         Resources resources = context.getResources();
-        CharSequence[] strings = new CharSequence[5];
-
+        ArrayList<CharSequence> strings = new ArrayList<CharSequence>();
+        
         // Number of albums selected.
         if (numOriginalSets == 1) {
-            strings[0] = "1 " + resources.getString(R.string.album_selected);
+            strings.add("1 " + resources.getString(R.string.album_selected));
         } else {
-            strings[0] = Integer.toString(numOriginalSets) + " " + resources.getString(R.string.albums_selected);
+            strings.add(Integer.toString(numOriginalSets) + " " + resources.getString(R.string.albums_selected));
         }
 
         // Number of items selected.
         int numItems = selectedItemsSet.mNumItemsLoaded;
         if (numItems == 1) {
-            strings[1] = "1 " + resources.getString(R.string.item_selected);
+            strings.add("1 " + resources.getString(R.string.item_selected));
         } else {
-            strings[1] = Integer.toString(numItems) + " " + resources.getString(R.string.items_selected);
+            strings.add(Integer.toString(numItems) + " " + resources.getString(R.string.items_selected));
         }
         
         DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.SHORT);
@@ -75,8 +75,8 @@ public final class DetailMode {
                 minTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(minTimestamp);
                 maxTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(maxTimestamp);
             }
-            strings[2] = resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp));
-            strings[3] = resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp));
+            strings.add(resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp)));
+            strings.add(resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp)));
         } else if (selectedItemsSet.areAddedTimestampsAvailable()) {
             long minTimestamp = selectedItemsSet.mMinAddedTimestamp;
             long maxTimestamp = selectedItemsSet.mMaxAddedTimestamp;
@@ -84,11 +84,11 @@ public final class DetailMode {
                 minTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(minTimestamp);
                 maxTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(maxTimestamp);
             }
-            strings[2] = resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp));
-            strings[3] = resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp));            
+            strings.add(resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp)));
+            strings.add(resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp)));            
         } else {
-            strings[2] = resources.getString(R.string.start) + ": " + resources.getString(R.string.date_unknown);
-            strings[3] = resources.getString(R.string.end) + ": " + resources.getString(R.string.date_unknown);
+            strings.add(resources.getString(R.string.start) + ": " + resources.getString(R.string.date_unknown));
+            strings.add(resources.getString(R.string.end) + ": " + resources.getString(R.string.date_unknown));
         }
 
         // The location of the selected items.
@@ -101,11 +101,15 @@ public final class DetailMode {
                 locationString = reverseGeocoder.computeMostGranularCommonLocation(selectedItemsSet);
             }
         }
-        if (locationString == null || locationString.length() == 0) {
-            locationString = resources.getString(R.string.location_unknown);
+        if (locationString != null && locationString.length() > 0) {
+               strings.add(resources.getString(R.string.location) + ": " + locationString);
         }
-        strings[4] = resources.getString(R.string.location) + ": " + locationString;
-        return strings;
+        int numStrings = strings.size();
+        CharSequence[] stringsArr = new CharSequence[numStrings];
+        for (int i = 0; i < numStrings; ++i) {
+               stringsArr[i] = strings.get(i);
+        }
+        return stringsArr;
     }
 
     private static CharSequence[] populateItemViewDetailModeStrings(Context context, MediaItem item) {
index dcadb4d..e0a5ab1 100644 (file)
@@ -76,7 +76,7 @@ public final class Gallery extends Activity {
                mRenderView.setRootLayer(mGridLayer);
                setContentView(mRenderView);
                
-               // Creating the DataSource objects
+               // Creating the DataSource objects.
                final PicasaDataSource picasaDataSource = new PicasaDataSource(this);
                final LocalDataSource localDataSource = new LocalDataSource(this);
                final ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
index 94a15d8..12b7032 100644 (file)
@@ -5,670 +5,671 @@ import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.os.SystemClock;
 import android.view.GestureDetector;
-import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 public final class GridInputProcessor implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
-    private int mCurrentFocusSlot;
-    private boolean mCurrentFocusIsPressed;
-    private int mCurrentSelectedSlot;
-
-    private float mPrevTiltValueLowPass;
-    private float mPrevShakeValueHighPass;
-    private float mShakeValue;
-    private int mTouchPosX;
-    private int mTouchPosY;
-    private int mActionCode;
-    private long mPrevTouchTime;
-    private float mFirstTouchPosX;
-    private float mFirstTouchPosY;
-    private float mPrevTouchPosX;
-    private float mPrevTouchPosY;
-    private float mTouchVelX;
-    private float mTouchVelY;
-    private boolean mProcessTouch;
-    private boolean mTouchMoved;
-    private float mDpadIgnoreTime = 0.0f;
-    private GridCamera mCamera;
-    private GridLayer mLayer;
-    private Context mContext;
-    private Pool<Vector3f> mPool;
-    private DisplayItem[] mDisplayItems;
-    private boolean mPrevHitEdge;
-    private boolean mTouchFeedbackDelivered;
-    private GestureDetector mGestureDetector;
-    private RenderView mView;
-
-    public GridInputProcessor(Context context, GridCamera camera, GridLayer layer, RenderView view, Pool<Vector3f> pool,
-            DisplayItem[] displayItems) {
-        mPool = pool;
-        mCamera = camera;
-        mLayer = layer;
-        mCurrentFocusSlot = Shared.INVALID;
-        mCurrentSelectedSlot = Shared.INVALID;
-        mContext = context;
-        mDisplayItems = displayItems;
-        mGestureDetector = new GestureDetector(context, this);
-        mGestureDetector.setIsLongpressEnabled(true);
-        mView = view;
-    }
-
-    public int getCurrentFocusSlot() {
-        return mCurrentFocusSlot;
-    }
-
-    public int getCurrentSelectedSlot() {
-        return mCurrentSelectedSlot;
-    }
-
-    public void setCurrentSelectedSlot(int slot) {
-        mCurrentSelectedSlot = slot;
-        GridLayer layer = mLayer;
-        layer.setState(GridLayer.STATE_FULL_SCREEN);
-        mCamera.mConvergenceSpeed = 2.0f;
-        DisplayItem displayItem = layer.getDisplayItemForSlotId(slot);
-        MediaItem item = null;
-        if (displayItem != null)
-            item = displayItem.mItemRef;
-        layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
-    }
-
-    public void onSensorChanged(RenderView view, SensorEvent event, int state) {
-        switch (event.sensor.getType()) {
-        case Sensor.TYPE_ACCELEROMETER:
-        case Sensor.TYPE_ORIENTATION:
-            float[] values = event.values;
-            float valueToUse = (mCamera.mWidth < mCamera.mHeight) ? values[0] : -values[1];
-            float tiltValue = 0.8f * mPrevTiltValueLowPass + 0.2f * valueToUse;
-            if (Math.abs(tiltValue) < 0.5f)
-                tiltValue = 0.0f;
-            if (state == GridLayer.STATE_FULL_SCREEN)
-                tiltValue = 0.0f;
-            if (tiltValue != 0.0f)
-                view.requestRender();
-            mCamera.mEyeOffsetX = -3.0f * tiltValue;
-            float shakeValue = values[1] * values[1] + values[2] * values[2];
-            mShakeValue = shakeValue - mPrevShakeValueHighPass;
-            mPrevShakeValueHighPass = shakeValue;
-            if (mShakeValue < 16.0f) {
-                mShakeValue = 0;
-            } else {
-                mShakeValue = mShakeValue * 4.0f;
-                if (mShakeValue > 200) {
-                    mShakeValue = 200;
-                }
-            }
-            break;
-        }
-    }
-
-    public boolean onTouchEvent(MotionEvent event) {
-        mTouchPosX = (int) (event.getX());
-        mTouchPosY = (int) (event.getY());
-        mActionCode = event.getAction();
-        long timestamp = SystemClock.elapsedRealtime();
-        long delta = timestamp - mPrevTouchTime;
-        mPrevTouchTime = timestamp;
-        float timeElapsed = (float) delta;
-        timeElapsed = timeElapsed * 0.001f; // division by 1000 for seconds
-        switch (mActionCode) {
-        case MotionEvent.ACTION_UP:
-            if (mProcessTouch == false) {
-                touchBegan(mTouchPosX, mTouchPosY);
-            }
-            touchEnded(mTouchPosX, mTouchPosY, timeElapsed);
-            break;
-        case MotionEvent.ACTION_DOWN:
-            mPrevTouchTime = timestamp;
-            touchBegan(mTouchPosX, mTouchPosY);
-            break;
-        case MotionEvent.ACTION_MOVE:
-            touchMoved(mTouchPosX, mTouchPosY, timeElapsed);
-            break;
-        }
-        mGestureDetector.onTouchEvent(event);
-        return true;
-    }
-
-    public boolean onKeyDown(int keyCode, KeyEvent event, int state) {
-        GridLayer layer = mLayer;
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            if (layer.getViewIntent())
-                return false;
-            if (layer.getHud().getMode() == HudLayer.MODE_SELECT) {
-                layer.deselectAll();
-                return true;
-            }
-            if (layer.inSlideShowMode()) {
-                layer.endSlideshow();
-                layer.getHud().setAlpha(1.0f);
-                return true;
-            }
-            float zoomValue = layer.getZoomValue();
-            if (zoomValue != 1.0f) {
-                layer.setZoomValue(1.0f);
-                layer.centerCameraForSlot(mCurrentSelectedSlot, 1.0f);
-                return true;
-            }
-            layer.goBack();
-            if (state == GridLayer.STATE_MEDIA_SETS)
-                return false;
-            return true;
-        }
-        if (mDpadIgnoreTime < 0.1f)
-            return true;
-        mDpadIgnoreTime = 0.0f;
-        IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
-        int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
-        int lastBufferedVisibleSlot = bufferedVisibleRange.end;
-        int anchorSlot = layer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER);
-        if (state == GridLayer.STATE_FULL_SCREEN) {
-            layer.endSlideshow();
-            boolean needsVibrate = false;
-            if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
-                needsVibrate = !layer.changeFocusToNextSlot(1.0f);
-            }
-            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
-                needsVibrate = !layer.changeFocusToPreviousSlot(1.0f);
-            }
-            if (needsVibrate) {
-                vibrateShort();
-            }
-            if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && !mCamera.isAnimating()) {
-                if (layer.getZoomValue() == 1.0f)
-                    layer.zoomInToSelectedItem();
-                else
-                    layer.setZoomValue(1.0f);
-            }
-            if (keyCode == KeyEvent.KEYCODE_MENU) {
-               if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
-                       return true;
-               }
-                if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
-                    layer.enterSelectionMode();
-                else
-                    layer.deselectAll();
-            }
-        } else {
-            mCurrentFocusIsPressed = false;
-            int numRows = ((GridLayoutInterface) layer.getLayoutInterface()).mNumRows;
-            if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && mCurrentFocusSlot != Shared.INVALID) {
-                if (layer.getHud().getMode() != HudLayer.MODE_SELECT) {
-                    boolean centerCamera = layer.tapGesture(mCurrentFocusSlot, false);
-                    if (centerCamera) {
-                        int slotId = mCurrentFocusSlot;
-                        selectSlot(slotId);
-                    }
-                    mCurrentFocusSlot = Shared.INVALID;
-                    return true;
-                } else {
-                    layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
-                }
-                mCurrentFocusIsPressed = true;
-            } else if (keyCode == KeyEvent.KEYCODE_MENU && mCurrentFocusSlot != Shared.INVALID) {
-                if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
-                    layer.enterSelectionMode();
-                else
-                    layer.deselectAll();
-            } else if (mCurrentFocusSlot == Shared.INVALID) {
-                mCurrentFocusSlot = anchorSlot;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
-                mCurrentFocusSlot += numRows;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
-                mCurrentFocusSlot -= numRows;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
-                --mCurrentFocusSlot;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
-                ++mCurrentFocusSlot;
-            }
-            if (mCurrentFocusSlot > lastBufferedVisibleSlot) {
-                mCurrentFocusSlot = lastBufferedVisibleSlot;
-            }
-            if (mCurrentFocusSlot < firstBufferedVisibleSlot)
-                mCurrentFocusSlot = firstBufferedVisibleSlot;
-            if (mCurrentFocusSlot != Shared.INVALID) {
-                layer.centerCameraForSlot(mCurrentFocusSlot, 1.0f);
-            }
-        }
-        return false;
-    }
-
-    private void touchBegan(int posX, int posY) {
-        mPrevTouchPosX = posX;
-        mPrevTouchPosY = posY;
-        mFirstTouchPosX = posX;
-        mFirstTouchPosY = posY;
-        mTouchVelX = 0;
-        mTouchVelY = 0;
-        mProcessTouch = true;
-        mTouchMoved = false;
-        mCamera.stopMovementInX();
-        GridLayer layer = mLayer;
-        mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
-        mCurrentFocusIsPressed = true;
-        mTouchFeedbackDelivered = false;
-        HudLayer hud = layer.getHud();
-        if (hud.getMode() == HudLayer.MODE_SELECT)
-            hud.closeSelectionMenu();
-        if (layer.getState() == GridLayer.STATE_FULL_SCREEN && hud.getMode() == HudLayer.MODE_SELECT) {
-            layer.deselectAll();
-            hud.setAlpha(1.0f);
-        }
-        int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
-        if (slotId != Shared.INVALID && layer.getState() != GridLayer.STATE_FULL_SCREEN) {
-            vibrateShort();
-        }
-    }
-
-    private void touchMoved(int posX, int posY, float timeElapsedx) {
-        if (mProcessTouch) {
-            GridLayer layer = mLayer;
-            GridCamera camera = mCamera;
-            float deltaX = -(posX - mPrevTouchPosX); // negation since the wall
-            // moves in a direction
-            // opposite to that of
-            // the touch
-            float deltaY = -(posY - mPrevTouchPosY);
-            if (Math.abs(deltaX) >= 10.0f || Math.abs(deltaY) >= 10.0f) {
-                mTouchMoved = true;
-            }
-            Pool<Vector3f> pool = mPool;
-            Vector3f firstPosition = pool.create();
-            Vector3f lastPosition = pool.create();
-            Vector3f deltaAnchorPosition = pool.create();
-            Vector3f worldPosDelta = pool.create();
-            try {
-                deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
-                LayoutInterface layout = layer.getLayoutInterface();
-                GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
-                int lastSlotIndex = 0;
-                IndexRange completeRange = layer.getCompleteRange();
-                synchronized (completeRange) {
-                    lastSlotIndex = completeRange.end;
-                }
-                GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
-
-                camera.convertToRelativeCameraSpace(deltaX, deltaY, 0, worldPosDelta);
-                deltaX = worldPosDelta.x;
-                deltaY = worldPosDelta.y;
-                camera.moveBy(deltaX, (layer.getZoomValue() == 1.0f) ? 0 : deltaY, 0);
-                deltaX *= camera.mScale;
-                deltaY *= camera.mScale;
-            } finally {
-                pool.delete(firstPosition);
-                pool.delete(lastPosition);
-                pool.delete(deltaAnchorPosition);
-                pool.delete(worldPosDelta);
-            }
-            if (layer.getZoomValue() == 1.0f) {
-                if (camera
-                        .computeConstraints(false, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition)) {
-                    deltaX = 0.0f;
-                    // vibrate
-                    if (!mTouchFeedbackDelivered) {
-                        mTouchFeedbackDelivered = true;
-                        vibrateLong();
-                    }
-                }
-            }
-            mTouchVelX = deltaX * timeElapsedx;
-            mTouchVelY = deltaY * timeElapsedx;
-            float maxVelXx = (mCamera.mWidth * 0.5f);
-            float maxVelYx = (mCamera.mHeight);
-            mTouchVelX = FloatUtils.clamp(mTouchVelX, -maxVelXx, maxVelXx);
-            mTouchVelY = FloatUtils.clamp(mTouchVelY, -maxVelYx, maxVelYx);
-            mPrevTouchPosX = posX;
-            mPrevTouchPosY = posY;
-            // you want the movement to track the finger immediately
-            if (mTouchMoved == false)
-                mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
-            else
-                mCurrentFocusSlot = Shared.INVALID;
-            if (!mCamera.isZAnimating()) {
-                mCamera.commitMoveInX();
-                mCamera.commitMoveInY();
-            }
-            int anchorSlotIndex = layer.getAnchorSlotIndex(GridLayer.ANCHOR_LEFT);
-            DisplayItem[] displayItems = mDisplayItems;
-            IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
-            int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
-            int lastBufferedVisibleSlot = bufferedVisibleRange.end;
-            synchronized (displayItems) {
-                if (anchorSlotIndex >= firstBufferedVisibleSlot && anchorSlotIndex <= lastBufferedVisibleSlot) {
-                    DisplayItem item = displayItems[(anchorSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
-                    if (item != null) {
-                        layer.getHud().setTimeBarTime(item.mItemRef.mDateTakenInMs);
-                    }
-                }
-            }
-        }
-    }
-
-    private void touchEnded(int posX, int posY, float timeElapsedx) {
-        if (mProcessTouch == false)
-            return;
-        int maxPixelsBeforeSwitch = mCamera.mWidth / 8;
-        mCamera.mConvergenceSpeed = 2.0f;
-        GridLayer layer = mLayer;
-        if (layer.getExpandedSlot() == Shared.INVALID && !layer.feedAboutToChange()) {
-            if (mCurrentSelectedSlot != Shared.INVALID) {
-                if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
-                    if (!mTouchMoved) {
-                        // tap gesture for fullscreen
-                        if (layer.getZoomValue() == 1.0f)
-                            layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
-                    } else if (layer.getZoomValue() == 1.0f) {
-                        // we want to snap to a new slotIndex based on where the
-                        // current position is
-                        if (layer.inSlideShowMode()) {
-                            layer.endSlideshow();
-                        }
-                        float deltaX = posX - mFirstTouchPosX;
-                        float deltaY = posY - mFirstTouchPosY;
-                        if (deltaY != 0) {
-                            // it has moved vertically
-                        }
-                        layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
-                        HudLayer hud = layer.getHud();
-                        if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                            layer.changeFocusToPreviousSlot(1.0f);
-                        } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                            layer.changeFocusToNextSlot(1.0f);
-                        }
-                    } else {
-                        // in zoomed state
-                        // we do nothing for now, but we should clamp to the
-                        // image bounds
-                        boolean hitEdge = layer.constrainCameraForSlot(mCurrentSelectedSlot);
-                        // mPrevHitEdge = false;
-                        if (hitEdge && mPrevHitEdge) {
-                            float deltaX = posX - mFirstTouchPosX;
-                            float deltaY = posY - mFirstTouchPosY;
-                            maxPixelsBeforeSwitch *= 4;
-                            if (deltaY != 0) {
-                                // it has moved vertically
-                            }
-                            mPrevHitEdge = false;
-                            HudLayer hud = layer.getHud();
-                            if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                                layer.changeFocusToPreviousSlot(1.0f);
-                            } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                                layer.changeFocusToNextSlot(1.0f);
-                            } else {
-                                mPrevHitEdge = hitEdge;
-                            }
-                        } else {
-                            mPrevHitEdge = hitEdge;
-                        }
-                    }
-                }
-            } else {
-                if (!layer.feedAboutToChange() && layer.getZoomValue() == 1.0f) {
-                    constrainCamera(true);
-                }
-            }
-        }
-        mCurrentFocusSlot = Shared.INVALID;
-        mCurrentFocusIsPressed = false;
-        mPrevTouchPosX = posX;
-        mPrevTouchPosY = posY;
-        mProcessTouch = false;
-    }
-
-    private void constrainCamera(boolean b) {
-        Pool<Vector3f> pool = mPool;
-        GridLayer layer = mLayer;
-        Vector3f firstPosition = pool.create();
-        Vector3f lastPosition = pool.create();
-        Vector3f deltaAnchorPosition = pool.create();
-        try {
-            deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
-            GridCamera camera = mCamera;
-            LayoutInterface layout = layer.getLayoutInterface();
-            GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
-            int lastSlotIndex = 0;
-            IndexRange completeRange = layer.getCompleteRange();
-            synchronized (completeRange) {
-                lastSlotIndex = completeRange.end;
-            }
-            GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
-            camera.computeConstraints(true, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition);
-        } finally {
-            pool.delete(firstPosition);
-            pool.delete(lastPosition);
-            pool.delete(deltaAnchorPosition);
-        }
-    }
-
-    public void clearSelection() {
-        mCurrentSelectedSlot = Shared.INVALID;
-    }
-
-    public void clearFocus() {
-        mCurrentFocusSlot = Shared.INVALID;
-    }
-
-    public boolean isFocusItemPressed() {
-        return mCurrentFocusIsPressed;
-    }
-
-    public void update(float timeElapsed) {
-        mDpadIgnoreTime += timeElapsed;
-    }
-
-    public void setCurrentFocusSlot(int slotId) {
-        mCurrentSelectedSlot = slotId;
-    }
-
-    public boolean onDown(MotionEvent e) {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-        if (mCurrentSelectedSlot == Shared.INVALID) {
-            mCamera.moveYTo(0);
-            mCamera.moveZTo(0);
-            mCamera.mConvergenceSpeed = 1.0f;
-            float normalizedVelocity = velocityX * mCamera.mOneByScale;
-            // mCamera.moveBy(-velocityX * mCamera.mOneByScale * 0.25f, 0, 0);
-            // constrainCamera(true);
-            IndexRange visibleRange = mLayer.getVisibleRange();
-            int numVisibleSlots = visibleRange.end - visibleRange.begin;
-            if (numVisibleSlots > 0) {
-                float fastFlingVelocity = 20.0f;
-                int slotsToSkip = (int) (numVisibleSlots * (-normalizedVelocity / fastFlingVelocity));
-                int maxSlots = numVisibleSlots;
-                if (slotsToSkip > maxSlots)
-                    slotsToSkip = maxSlots;
-                if (slotsToSkip < -maxSlots)
-                    slotsToSkip = -maxSlots;
-                if (Math.abs(slotsToSkip) <= 1) {
-                    if (velocityX > 0)
-                        slotsToSkip = -2;
-                    else if (velocityX < 0)
-                        slotsToSkip = 2;
-                }
-                int slotToGetTo = mLayer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER) + slotsToSkip;
-                if (slotToGetTo < 0)
-                    slotToGetTo = 0;
-                int lastSlot = mLayer.getCompleteRange().end;
-                if (slotToGetTo > lastSlot)
-                    slotToGetTo = lastSlot;
-                mLayer.centerCameraForSlot(slotToGetTo, 1.0f);
-            }
-            constrainCamera(true);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public void onLongPress(MotionEvent e) {
-        if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
-            HudLayer hud = mLayer.getHud();
-            hud.getPathBar().setHidden(true);
-            hud.getMenuBar().setHidden(true);
-            if (hud.getMode() != HudLayer.MODE_NORMAL)
-                hud.setMode(HudLayer.MODE_NORMAL);
-        }
-        if (mCurrentFocusSlot != Shared.INVALID) {
-            vibrateLong();
-            GridLayer layer = mLayer;
-            if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
-                layer.deselectAll();
-            }
-            HudLayer hud = layer.getHud();
-            hud.enterSelectionMode();
-            layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
-        }
-    }
-
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public void onShowPress(MotionEvent e) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public boolean onSingleTapUp(MotionEvent e) {
-        GridLayer layer = mLayer;
-        int posX = (int) e.getX();
-        int posY = (int) e.getY();
-        if (mCurrentSelectedSlot != Shared.INVALID) {
-            // Fullscreen mode.
-            mCamera.mConvergenceSpeed = 2.0f;
-            int slotId = mCurrentSelectedSlot;
-            if (layer.getZoomValue() == 1.0f) {
-                layer.centerCameraForSlot(slotId, 1.0f);
-            } else {
-                layer.constrainCameraForSlot(slotId);
-            }
-            DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
-            if (displayItem != null) {
-                final MediaItem item = displayItem.mItemRef;
-                int heightBy2 = mCamera.mHeight / 2;
-                boolean posYInBounds = (Math.abs(posY - heightBy2) < 64);
-                if (posX < 32 && posYInBounds) {
-                    layer.changeFocusToPreviousSlot(1.0f);
-                } else if (posX > mCamera.mWidth - 32 && posYInBounds) {
-                    layer.changeFocusToNextSlot(1.0f);
-                } else if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
-                    Utils.playVideo(mContext, item);
-                } else {
-                    // We stop any slideshow.
-                    HudLayer hud = layer.getHud();
-                    if (layer.inSlideShowMode()) {
-                        layer.endSlideshow();
-                    } else {
-                        hud.setAlpha(1.0f - hud.getAlpha());
-                    }
-                    if (hud.getMode() == HudLayer.MODE_SELECT) {
-                        hud.setAlpha(1.0f);
-                    }
-                }
-            }
-        } else {
-            int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
-            if (slotId != Shared.INVALID) {
-                HudLayer hud = layer.getHud();
-                if (hud.getMode() == HudLayer.MODE_SELECT) {
-                    layer.addSlotToSelectedItems(slotId, true, true);
-                } else {
-                    boolean centerCamera = (mCurrentSelectedSlot == Shared.INVALID) ? layer.tapGesture(slotId, false) : true;
-                    if (centerCamera) {
-                        // We check if this item is a video or not.
-                        selectSlot(slotId);
-                    }
-                }
-            } else {
-                int state = layer.getState();
-                if (state != GridLayer.STATE_FULL_SCREEN && state != GridLayer.STATE_GRID_VIEW
-                        && layer.getHud().getMode() != HudLayer.MODE_SELECT) {
-                    slotId = layer.getMetadataSlotIndexForScreenPosition(posX, posY);
-                    if (slotId != Shared.INVALID) {
-                        layer.tapGesture(slotId, true);
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    private void selectSlot(int slotId) {
-        GridLayer layer = mLayer;
-        if (layer.getState() == GridLayer.STATE_GRID_VIEW) {
-            DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
-            if (displayItem != null) {
-                final MediaItem item = displayItem.mItemRef;
-                if (layer.getPickIntent()) {
-                    // we need to return this item
-                    ((Gallery) mContext).getHandler().post(new Runnable() {
-                        public void run() {
-                            ((Gallery) mContext).launchCropperOrFinish(item);
-                        }
-                    });
-                    return;
-                }
-                if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
-                    Utils.playVideo(mContext, item);
-                } else {
-                    mCurrentSelectedSlot = slotId;
-                    layer.endSlideshow();
-                    layer.setState(GridLayer.STATE_FULL_SCREEN);
-                    mCamera.mConvergenceSpeed = 2.0f;
-                    layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
-                }
-            }
-        }
-    }
-
-    public boolean onDoubleTap(MotionEvent e) {
-        final GridLayer layer = mLayer;
-        if (layer.getState() == GridLayer.STATE_FULL_SCREEN && !mCamera.isZAnimating()) {
-            float posX = e.getX();
-            float posY = e.getY();
-            final Vector3f retVal = new Vector3f();
-            posX -= (mCamera.mWidth / 2);
-            posY -= (mCamera.mHeight / 2);
-            mCamera.convertToRelativeCameraSpace(posX, posY, 0, retVal);
-            if (layer.getZoomValue() == 1.0f) {
-                layer.setZoomValue(3f);
-                mCamera.update(0.001f);
-                mCamera.moveBy(retVal.x, retVal.y, 0);
-                layer.constrainCameraForSlot(mCurrentSelectedSlot);
-            } else {
-                layer.setZoomValue(1.0f);
-            }
-            mCamera.mConvergenceSpeed = 2.0f;
-        } else {
-            return onSingleTapConfirmed(e);
-        }
-        return true;
-    }
-
-    public boolean onDoubleTapEvent(MotionEvent e) {
-        return false;
-    }
-
-    public boolean onSingleTapConfirmed(MotionEvent e) {
-        return false;
-    }
-
-    public boolean touchPressed() {
-        return mProcessTouch;
-    }
-
-    private void vibrateShort() {
-        // As per request by Google, this line disables vibration.
-        //mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-    }
-
-    private void vibrateLong() {
-        //mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-    }
+       private int mCurrentFocusSlot;
+       private boolean mCurrentFocusIsPressed;
+       private int mCurrentSelectedSlot;
+
+       private float mPrevTiltValueLowPass;
+       private float mPrevShakeValueHighPass;
+       private float mShakeValue;
+       private int mTouchPosX;
+       private int mTouchPosY;
+       private int mActionCode;
+       private long mPrevTouchTime;
+       private float mFirstTouchPosX;
+       private float mFirstTouchPosY;
+       private float mPrevTouchPosX;
+       private float mPrevTouchPosY;
+       private float mTouchVelX;
+       private float mTouchVelY;
+       private boolean mProcessTouch;
+       private boolean mTouchMoved;
+       private float mDpadIgnoreTime = 0.0f;
+       private GridCamera mCamera;
+       private GridLayer mLayer;
+       private Context mContext;
+       private Pool<Vector3f> mPool;
+       private DisplayItem[] mDisplayItems;
+       private boolean mPrevHitEdge;
+       private boolean mTouchFeedbackDelivered;
+       private GestureDetector mGestureDetector;
+
+       public GridInputProcessor(Context context, GridCamera camera, GridLayer layer, RenderView view, Pool<Vector3f> pool,
+               DisplayItem[] displayItems) {
+               mPool = pool;
+               mCamera = camera;
+               mLayer = layer;
+               mCurrentFocusSlot = Shared.INVALID;
+               mCurrentSelectedSlot = Shared.INVALID;
+               mContext = context;
+               mDisplayItems = displayItems;
+               mGestureDetector = new GestureDetector(context, this);
+               mGestureDetector.setIsLongpressEnabled(true);
+       }
+
+       public int getCurrentFocusSlot() {
+               return mCurrentFocusSlot;
+       }
+
+       public int getCurrentSelectedSlot() {
+               return mCurrentSelectedSlot;
+       }
+
+       public void setCurrentSelectedSlot(int slot) {
+               mCurrentSelectedSlot = slot;
+               GridLayer layer = mLayer;
+               layer.setState(GridLayer.STATE_FULL_SCREEN);
+               mCamera.mConvergenceSpeed = 2.0f;
+               DisplayItem displayItem = layer.getDisplayItemForSlotId(slot);
+               MediaItem item = null;
+               if (displayItem != null)
+                       item = displayItem.mItemRef;
+               layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
+       }
+
+       public void onSensorChanged(RenderView view, SensorEvent event, int state) {
+               switch (event.sensor.getType()) {
+               case Sensor.TYPE_ACCELEROMETER:
+               case Sensor.TYPE_ORIENTATION:
+                       float[] values = event.values;
+                       float valueToUse = (mCamera.mWidth < mCamera.mHeight) ? values[0] : -values[1];
+                       float tiltValue = 0.8f * mPrevTiltValueLowPass + 0.2f * valueToUse;
+                       if (Math.abs(tiltValue) < 0.5f)
+                               tiltValue = 0.0f;
+                       if (state == GridLayer.STATE_FULL_SCREEN)
+                               tiltValue = 0.0f;
+                       if (tiltValue != 0.0f)
+                               view.requestRender();
+                       mCamera.mEyeOffsetX = -3.0f * tiltValue;
+                       float shakeValue = values[1] * values[1] + values[2] * values[2];
+                       mShakeValue = shakeValue - mPrevShakeValueHighPass;
+                       mPrevShakeValueHighPass = shakeValue;
+                       if (mShakeValue < 16.0f) {
+                               mShakeValue = 0;
+                       } else {
+                               mShakeValue = mShakeValue * 4.0f;
+                               if (mShakeValue > 200) {
+                                       mShakeValue = 200;
+                               }
+                       }
+                       break;
+               }
+       }
+
+       public boolean onTouchEvent(MotionEvent event) {
+               mTouchPosX = (int) (event.getX());
+               mTouchPosY = (int) (event.getY());
+               mActionCode = event.getAction();
+               long timestamp = SystemClock.elapsedRealtime();
+               long delta = timestamp - mPrevTouchTime;
+               mPrevTouchTime = timestamp;
+               float timeElapsed = (float) delta;
+               timeElapsed = timeElapsed * 0.001f; // division by 1000 for seconds
+               switch (mActionCode) {
+               case MotionEvent.ACTION_UP:
+                       if (mProcessTouch == false) {
+                               touchBegan(mTouchPosX, mTouchPosY);
+                       }
+                       touchEnded(mTouchPosX, mTouchPosY, timeElapsed);
+                       break;
+               case MotionEvent.ACTION_DOWN:
+                       mPrevTouchTime = timestamp;
+                       touchBegan(mTouchPosX, mTouchPosY);
+                       break;
+               case MotionEvent.ACTION_MOVE:
+                       touchMoved(mTouchPosX, mTouchPosY, timeElapsed);
+                       break;
+               }
+               mGestureDetector.onTouchEvent(event);
+               return true;
+       }
+
+       public boolean onKeyDown(int keyCode, KeyEvent event, int state) {
+               GridLayer layer = mLayer;
+               if (keyCode == KeyEvent.KEYCODE_BACK) {
+                       if (layer.getViewIntent())
+                               return false;
+                       if (layer.getHud().getMode() == HudLayer.MODE_SELECT) {
+                               layer.deselectAll();
+                               return true;
+                       }
+                       if (layer.inSlideShowMode()) {
+                               layer.endSlideshow();
+                               layer.getHud().setAlpha(1.0f);
+                               return true;
+                       }
+                       float zoomValue = layer.getZoomValue();
+                       if (zoomValue != 1.0f) {
+                               layer.setZoomValue(1.0f);
+                               layer.centerCameraForSlot(mCurrentSelectedSlot, 1.0f);
+                               return true;
+                       }
+                       layer.goBack();
+                       if (state == GridLayer.STATE_MEDIA_SETS)
+                               return false;
+                       return true;
+               }
+               if (mDpadIgnoreTime < 0.1f)
+                       return true;
+               mDpadIgnoreTime = 0.0f;
+               IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
+               int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
+               int lastBufferedVisibleSlot = bufferedVisibleRange.end;
+               int anchorSlot = layer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER);
+               if (state == GridLayer.STATE_FULL_SCREEN) {
+                       if (keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN
+                               && keyCode != KeyEvent.KEYCODE_MUTE && keyCode != KeyEvent.KEYCODE_HEADSETHOOK
+                               && keyCode != KeyEvent.KEYCODE_NOTIFICATION) {
+                               layer.endSlideshow();
+                       }
+                       boolean needsVibrate = false;
+                       if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+                               needsVibrate = !layer.changeFocusToNextSlot(1.0f);
+                       }
+                       if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+                               needsVibrate = !layer.changeFocusToPreviousSlot(1.0f);
+                       }
+                       if (needsVibrate) {
+                               vibrateShort();
+                       }
+                       if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && !mCamera.isAnimating()) {
+                               if (layer.getZoomValue() == 1.0f)
+                                       layer.zoomInToSelectedItem();
+                               else
+                                       layer.setZoomValue(1.0f);
+                       }
+                       if (keyCode == KeyEvent.KEYCODE_MENU) {
+                               if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
+                                       return true;
+                               }
+                               if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
+                                       layer.enterSelectionMode();
+                               else
+                                       layer.deselectAll();
+                       }
+               } else {
+                       mCurrentFocusIsPressed = false;
+                       int numRows = ((GridLayoutInterface) layer.getLayoutInterface()).mNumRows;
+                       if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && mCurrentFocusSlot != Shared.INVALID) {
+                               if (layer.getHud().getMode() != HudLayer.MODE_SELECT) {
+                                       boolean centerCamera = layer.tapGesture(mCurrentFocusSlot, false);
+                                       if (centerCamera) {
+                                               int slotId = mCurrentFocusSlot;
+                                               selectSlot(slotId);
+                                       }
+                                       mCurrentFocusSlot = Shared.INVALID;
+                                       return true;
+                               } else {
+                                       layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
+                               }
+                               mCurrentFocusIsPressed = true;
+                       } else if (keyCode == KeyEvent.KEYCODE_MENU && mCurrentFocusSlot != Shared.INVALID) {
+                               if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
+                                       layer.enterSelectionMode();
+                               else
+                                       layer.deselectAll();
+                       } else if (mCurrentFocusSlot == Shared.INVALID) {
+                               mCurrentFocusSlot = anchorSlot;
+                       } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+                               mCurrentFocusSlot += numRows;
+                       } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+                               mCurrentFocusSlot -= numRows;
+                       } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+                               --mCurrentFocusSlot;
+                       } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+                               ++mCurrentFocusSlot;
+                       }
+                       if (mCurrentFocusSlot > lastBufferedVisibleSlot) {
+                               mCurrentFocusSlot = lastBufferedVisibleSlot;
+                       }
+                       if (mCurrentFocusSlot < firstBufferedVisibleSlot)
+                               mCurrentFocusSlot = firstBufferedVisibleSlot;
+                       if (mCurrentFocusSlot != Shared.INVALID) {
+                               layer.centerCameraForSlot(mCurrentFocusSlot, 1.0f);
+                       }
+               }
+               return false;
+       }
+
+       private void touchBegan(int posX, int posY) {
+               mPrevTouchPosX = posX;
+               mPrevTouchPosY = posY;
+               mFirstTouchPosX = posX;
+               mFirstTouchPosY = posY;
+               mTouchVelX = 0;
+               mTouchVelY = 0;
+               mProcessTouch = true;
+               mTouchMoved = false;
+               mCamera.stopMovementInX();
+               GridLayer layer = mLayer;
+               mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
+               mCurrentFocusIsPressed = true;
+               mTouchFeedbackDelivered = false;
+               HudLayer hud = layer.getHud();
+               if (hud.getMode() == HudLayer.MODE_SELECT)
+                       hud.closeSelectionMenu();
+               if (layer.getState() == GridLayer.STATE_FULL_SCREEN && hud.getMode() == HudLayer.MODE_SELECT) {
+                       layer.deselectAll();
+                       hud.setAlpha(1.0f);
+               }
+               int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
+               if (slotId != Shared.INVALID && layer.getState() != GridLayer.STATE_FULL_SCREEN) {
+                       vibrateShort();
+               }
+       }
+
+       private void touchMoved(int posX, int posY, float timeElapsedx) {
+               if (mProcessTouch) {
+                       GridLayer layer = mLayer;
+                       GridCamera camera = mCamera;
+                       float deltaX = -(posX - mPrevTouchPosX); // negation since the wall
+                       // moves in a direction
+                       // opposite to that of
+                       // the touch
+                       float deltaY = -(posY - mPrevTouchPosY);
+                       if (Math.abs(deltaX) >= 10.0f || Math.abs(deltaY) >= 10.0f) {
+                               mTouchMoved = true;
+                       }
+                       Pool<Vector3f> pool = mPool;
+                       Vector3f firstPosition = pool.create();
+                       Vector3f lastPosition = pool.create();
+                       Vector3f deltaAnchorPosition = pool.create();
+                       Vector3f worldPosDelta = pool.create();
+                       try {
+                               deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
+                               LayoutInterface layout = layer.getLayoutInterface();
+                               GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
+                               int lastSlotIndex = 0;
+                               IndexRange completeRange = layer.getCompleteRange();
+                               synchronized (completeRange) {
+                                       lastSlotIndex = completeRange.end;
+                               }
+                               GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
+
+                               camera.convertToRelativeCameraSpace(deltaX, deltaY, 0, worldPosDelta);
+                               deltaX = worldPosDelta.x;
+                               deltaY = worldPosDelta.y;
+                               camera.moveBy(deltaX, (layer.getZoomValue() == 1.0f) ? 0 : deltaY, 0);
+                               deltaX *= camera.mScale;
+                               deltaY *= camera.mScale;
+                       } finally {
+                               pool.delete(firstPosition);
+                               pool.delete(lastPosition);
+                               pool.delete(deltaAnchorPosition);
+                               pool.delete(worldPosDelta);
+                       }
+                       if (layer.getZoomValue() == 1.0f) {
+                               if (camera
+                                       .computeConstraints(false, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition)) {
+                                       deltaX = 0.0f;
+                                       // vibrate
+                                       if (!mTouchFeedbackDelivered) {
+                                               mTouchFeedbackDelivered = true;
+                                               vibrateLong();
+                                       }
+                               }
+                       }
+                       mTouchVelX = deltaX * timeElapsedx;
+                       mTouchVelY = deltaY * timeElapsedx;
+                       float maxVelXx = (mCamera.mWidth * 0.5f);
+                       float maxVelYx = (mCamera.mHeight);
+                       mTouchVelX = FloatUtils.clamp(mTouchVelX, -maxVelXx, maxVelXx);
+                       mTouchVelY = FloatUtils.clamp(mTouchVelY, -maxVelYx, maxVelYx);
+                       mPrevTouchPosX = posX;
+                       mPrevTouchPosY = posY;
+                       // you want the movement to track the finger immediately
+                       if (mTouchMoved == false)
+                               mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
+                       else
+                               mCurrentFocusSlot = Shared.INVALID;
+                       if (!mCamera.isZAnimating()) {
+                               mCamera.commitMoveInX();
+                               mCamera.commitMoveInY();
+                       }
+                       int anchorSlotIndex = layer.getAnchorSlotIndex(GridLayer.ANCHOR_LEFT);
+                       DisplayItem[] displayItems = mDisplayItems;
+                       IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
+                       int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
+                       int lastBufferedVisibleSlot = bufferedVisibleRange.end;
+                       synchronized (displayItems) {
+                               if (anchorSlotIndex >= firstBufferedVisibleSlot && anchorSlotIndex <= lastBufferedVisibleSlot) {
+                                       DisplayItem item = displayItems[(anchorSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
+                                       if (item != null) {
+                                               layer.getHud().setTimeBarTime(item.mItemRef.mDateTakenInMs);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       private void touchEnded(int posX, int posY, float timeElapsedx) {
+               if (mProcessTouch == false)
+                       return;
+               int maxPixelsBeforeSwitch = mCamera.mWidth / 8;
+               mCamera.mConvergenceSpeed = 2.0f;
+               GridLayer layer = mLayer;
+               if (layer.getExpandedSlot() == Shared.INVALID && !layer.feedAboutToChange()) {
+                       if (mCurrentSelectedSlot != Shared.INVALID) {
+                               if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
+                                       if (!mTouchMoved) {
+                                               // tap gesture for fullscreen
+                                               if (layer.getZoomValue() == 1.0f)
+                                                       layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
+                                       } else if (layer.getZoomValue() == 1.0f) {
+                                               // we want to snap to a new slotIndex based on where the
+                                               // current position is
+                                               if (layer.inSlideShowMode()) {
+                                                       layer.endSlideshow();
+                                               }
+                                               float deltaX = posX - mFirstTouchPosX;
+                                               float deltaY = posY - mFirstTouchPosY;
+                                               if (deltaY != 0) {
+                                                       // it has moved vertically
+                                               }
+                                               layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
+                                               HudLayer hud = layer.getHud();
+                                               if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+                                                       layer.changeFocusToPreviousSlot(1.0f);
+                                               } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+                                                       layer.changeFocusToNextSlot(1.0f);
+                                               }
+                                       } else {
+                                               // in zoomed state
+                                               // we do nothing for now, but we should clamp to the
+                                               // image bounds
+                                               boolean hitEdge = layer.constrainCameraForSlot(mCurrentSelectedSlot);
+                                               // mPrevHitEdge = false;
+                                               if (hitEdge && mPrevHitEdge) {
+                                                       float deltaX = posX - mFirstTouchPosX;
+                                                       float deltaY = posY - mFirstTouchPosY;
+                                                       maxPixelsBeforeSwitch *= 4;
+                                                       if (deltaY != 0) {
+                                                               // it has moved vertically
+                                                       }
+                                                       mPrevHitEdge = false;
+                                                       HudLayer hud = layer.getHud();
+                                                       if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+                                                               layer.changeFocusToPreviousSlot(1.0f);
+                                                       } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+                                                               layer.changeFocusToNextSlot(1.0f);
+                                                       } else {
+                                                               mPrevHitEdge = hitEdge;
+                                                       }
+                                               } else {
+                                                       mPrevHitEdge = hitEdge;
+                                               }
+                                       }
+                               }
+                       } else {
+                               if (!layer.feedAboutToChange() && layer.getZoomValue() == 1.0f) {
+                                       constrainCamera(true);
+                               }
+                       }
+               }
+               mCurrentFocusSlot = Shared.INVALID;
+               mCurrentFocusIsPressed = false;
+               mPrevTouchPosX = posX;
+               mPrevTouchPosY = posY;
+               mProcessTouch = false;
+       }
+
+       private void constrainCamera(boolean b) {
+               Pool<Vector3f> pool = mPool;
+               GridLayer layer = mLayer;
+               Vector3f firstPosition = pool.create();
+               Vector3f lastPosition = pool.create();
+               Vector3f deltaAnchorPosition = pool.create();
+               try {
+                       deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
+                       GridCamera camera = mCamera;
+                       LayoutInterface layout = layer.getLayoutInterface();
+                       GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
+                       int lastSlotIndex = 0;
+                       IndexRange completeRange = layer.getCompleteRange();
+                       synchronized (completeRange) {
+                               lastSlotIndex = completeRange.end;
+                       }
+                       GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
+                       camera.computeConstraints(true, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition);
+               } finally {
+                       pool.delete(firstPosition);
+                       pool.delete(lastPosition);
+                       pool.delete(deltaAnchorPosition);
+               }
+       }
+
+       public void clearSelection() {
+               mCurrentSelectedSlot = Shared.INVALID;
+       }
+
+       public void clearFocus() {
+               mCurrentFocusSlot = Shared.INVALID;
+       }
+
+       public boolean isFocusItemPressed() {
+               return mCurrentFocusIsPressed;
+       }
+
+       public void update(float timeElapsed) {
+               mDpadIgnoreTime += timeElapsed;
+       }
+
+       public void setCurrentFocusSlot(int slotId) {
+               mCurrentSelectedSlot = slotId;
+       }
+
+       public boolean onDown(MotionEvent e) {
+               // TODO Auto-generated method stub
+               return true;
+       }
+
+       public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+               if (mCurrentSelectedSlot == Shared.INVALID) {
+                       mCamera.moveYTo(0);
+                       mCamera.moveZTo(0);
+                       mCamera.mConvergenceSpeed = 1.0f;
+                       float normalizedVelocity = velocityX * mCamera.mOneByScale;
+                       // mCamera.moveBy(-velocityX * mCamera.mOneByScale * 0.25f, 0, 0);
+                       // constrainCamera(true);
+                       IndexRange visibleRange = mLayer.getVisibleRange();
+                       int numVisibleSlots = visibleRange.end - visibleRange.begin;
+                       if (numVisibleSlots > 0) {
+                               float fastFlingVelocity = 20.0f;
+                               int slotsToSkip = (int) (numVisibleSlots * (-normalizedVelocity / fastFlingVelocity));
+                               int maxSlots = numVisibleSlots;
+                               if (slotsToSkip > maxSlots)
+                                       slotsToSkip = maxSlots;
+                               if (slotsToSkip < -maxSlots)
+                                       slotsToSkip = -maxSlots;
+                               if (Math.abs(slotsToSkip) <= 1) {
+                                       if (velocityX > 0)
+                                               slotsToSkip = -2;
+                                       else if (velocityX < 0)
+                                               slotsToSkip = 2;
+                               }
+                               int slotToGetTo = mLayer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER) + slotsToSkip;
+                               if (slotToGetTo < 0)
+                                       slotToGetTo = 0;
+                               int lastSlot = mLayer.getCompleteRange().end;
+                               if (slotToGetTo > lastSlot)
+                                       slotToGetTo = lastSlot;
+                               mLayer.centerCameraForSlot(slotToGetTo, 1.0f);
+                       }
+                       constrainCamera(true);
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
+       public void onLongPress(MotionEvent e) {
+               if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
+                       HudLayer hud = mLayer.getHud();
+                       hud.getPathBar().setHidden(true);
+                       hud.getMenuBar().setHidden(true);
+                       if (hud.getMode() != HudLayer.MODE_NORMAL)
+                               hud.setMode(HudLayer.MODE_NORMAL);
+               }
+               if (mCurrentFocusSlot != Shared.INVALID) {
+                       vibrateLong();
+                       GridLayer layer = mLayer;
+                       if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
+                               layer.deselectAll();
+                       }
+                       HudLayer hud = layer.getHud();
+                       hud.enterSelectionMode();
+                       layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
+               }
+       }
+
+       public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       public void onShowPress(MotionEvent e) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public boolean onSingleTapUp(MotionEvent e) {
+               GridLayer layer = mLayer;
+               int posX = (int) e.getX();
+               int posY = (int) e.getY();
+               if (mCurrentSelectedSlot != Shared.INVALID) {
+                       // Fullscreen mode.
+                       mCamera.mConvergenceSpeed = 2.0f;
+                       int slotId = mCurrentSelectedSlot;
+                       if (layer.getZoomValue() == 1.0f) {
+                               layer.centerCameraForSlot(slotId, 1.0f);
+                       } else {
+                               layer.constrainCameraForSlot(slotId);
+                       }
+                       DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
+                       if (displayItem != null) {
+                               final MediaItem item = displayItem.mItemRef;
+                               int heightBy2 = mCamera.mHeight / 2;
+                               boolean posYInBounds = (Math.abs(posY - heightBy2) < 64);
+                               if (posX < 32 && posYInBounds) {
+                                       layer.changeFocusToPreviousSlot(1.0f);
+                               } else if (posX > mCamera.mWidth - 32 && posYInBounds) {
+                                       layer.changeFocusToNextSlot(1.0f);
+                               } else if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
+                                       Utils.playVideo(mContext, item);
+                               } else {
+                                       // We stop any slideshow.
+                                       HudLayer hud = layer.getHud();
+                                       if (layer.inSlideShowMode()) {
+                                               layer.endSlideshow();
+                                       } else {
+                                               hud.setAlpha(1.0f - hud.getAlpha());
+                                       }
+                                       if (hud.getMode() == HudLayer.MODE_SELECT) {
+                                               hud.setAlpha(1.0f);
+                                       }
+                               }
+                       }
+               } else {
+                       int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
+                       if (slotId != Shared.INVALID) {
+                               HudLayer hud = layer.getHud();
+                               if (hud.getMode() == HudLayer.MODE_SELECT) {
+                                       layer.addSlotToSelectedItems(slotId, true, true);
+                               } else {
+                                       boolean centerCamera = (mCurrentSelectedSlot == Shared.INVALID) ? layer.tapGesture(slotId, false) : true;
+                                       if (centerCamera) {
+                                               // We check if this item is a video or not.
+                                               selectSlot(slotId);
+                                       }
+                               }
+                       } else {
+                               int state = layer.getState();
+                               if (state != GridLayer.STATE_FULL_SCREEN && state != GridLayer.STATE_GRID_VIEW
+                                       && layer.getHud().getMode() != HudLayer.MODE_SELECT) {
+                                       slotId = layer.getMetadataSlotIndexForScreenPosition(posX, posY);
+                                       if (slotId != Shared.INVALID) {
+                                               layer.tapGesture(slotId, true);
+                                       }
+                               }
+                       }
+               }
+               return true;
+       }
+
+       private void selectSlot(int slotId) {
+               GridLayer layer = mLayer;
+               if (layer.getState() == GridLayer.STATE_GRID_VIEW) {
+                       DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
+                       if (displayItem != null) {
+                               final MediaItem item = displayItem.mItemRef;
+                               if (layer.getPickIntent()) {
+                                       // we need to return this item
+                                       ((Gallery) mContext).getHandler().post(new Runnable() {
+                                               public void run() {
+                                                       ((Gallery) mContext).launchCropperOrFinish(item);
+                                               }
+                                       });
+                                       return;
+                               }
+                               if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
+                                       Utils.playVideo(mContext, item);
+                               } else {
+                                       mCurrentSelectedSlot = slotId;
+                                       layer.endSlideshow();
+                                       layer.setState(GridLayer.STATE_FULL_SCREEN);
+                                       mCamera.mConvergenceSpeed = 2.0f;
+                                       layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
+                               }
+                       }
+               }
+       }
+
+       public boolean onDoubleTap(MotionEvent e) {
+               final GridLayer layer = mLayer;
+               if (layer.getState() == GridLayer.STATE_FULL_SCREEN && !mCamera.isZAnimating()) {
+                       float posX = e.getX();
+                       float posY = e.getY();
+                       final Vector3f retVal = new Vector3f();
+                       posX -= (mCamera.mWidth / 2);
+                       posY -= (mCamera.mHeight / 2);
+                       mCamera.convertToRelativeCameraSpace(posX, posY, 0, retVal);
+                       if (layer.getZoomValue() == 1.0f) {
+                               layer.setZoomValue(3f);
+                               mCamera.update(0.001f);
+                               mCamera.moveBy(retVal.x, retVal.y, 0);
+                               layer.constrainCameraForSlot(mCurrentSelectedSlot);
+                       } else {
+                               layer.setZoomValue(1.0f);
+                       }
+                       mCamera.mConvergenceSpeed = 2.0f;
+               } else {
+                       return onSingleTapConfirmed(e);
+               }
+               return true;
+       }
+
+       public boolean onDoubleTapEvent(MotionEvent e) {
+               return false;
+       }
+
+       public boolean onSingleTapConfirmed(MotionEvent e) {
+               return false;
+       }
+
+       public boolean touchPressed() {
+               return mProcessTouch;
+       }
+
+       private void vibrateShort() {
+               // As per request by Google, this line disables vibration.
+               // mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+       }
+
+       private void vibrateLong() {
+               // mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+       }
 }
index 61bea47..2693752 100644 (file)
@@ -59,14 +59,14 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
        private static Vector3f sDeltaAnchorPosition = new Vector3f();
 
        // The display primitives.
-       private GridDrawables mDrawables;
+       final private GridDrawables mDrawables;
        private float mSelectedAlpha = 0.0f;
        private float mTargetAlpha = 0.0f;
 
-       private GridCamera mCamera;
-       private GridCameraManager mCameraManager;
-       private GridDrawManager mDrawManager;
-       private GridInputProcessor mInputProcessor;
+       final private GridCamera mCamera;
+       final private GridCameraManager mCameraManager;
+       final private GridDrawManager mDrawManager;
+       final private GridInputProcessor mInputProcessor;
 
        private boolean mFeedAboutToChange;
        private boolean mPerformingLayoutChange;
@@ -85,7 +85,7 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
        private static ArrayList<MediaItem> sVisibleItems;
 
        private float mTimeElapsedSinceTransition;
-       private BackgroundLayer mBackground;
+       private final BackgroundLayer mBackground;
        private boolean mLocationFilter;
        private float mZoomValue = 1.0f;
        private float mCurrentFocusItemWidth = 1.0f;
@@ -107,13 +107,11 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
        private int mFramesDirty;
        private String mRequestFocusContentUri;
        private int mFrameCount;
-       private boolean mNeedsInit;
 
        public GridLayer(Context context, int itemWidth, int itemHeight, LayoutInterface layoutInterface, RenderView view) {
                mBackground = new BackgroundLayer(this);
                mContext = context;
                mView = view;
-               mNeedsInit = true;
 
                DisplaySlot[] displaySlots = sDisplaySlots;
                for (int i = 0; i < MAX_DISPLAY_SLOTS; ++i) {
@@ -165,7 +163,6 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
                        mMediaFeed.shutdown();
                }
                mContext = null;
-               mBackground = null;
                sBucketList.clear();
                mView = null;
        }
index 1ff37a3..f93d559 100644 (file)
@@ -111,7 +111,6 @@ public final class LocalDataSource implements DataSource {
         if (setIdToUse == Shared.INVALID) {
             return;
         }
-        Log.i(TAG, "Refreshing local data source");
         if (feed.getMediaSet(setIdToUse) == null) {
             MediaSet mediaSet = feed.addMediaSet(setIdToUse, this);
             if (setIdToUse == CAMERA_BUCKET_ID) {
@@ -122,6 +121,7 @@ public final class LocalDataSource implements DataSource {
             mediaSet.generateTitle(true);
         } else {
             MediaSet mediaSet = feed.replaceMediaSet(setIdToUse, this);
+            Log.i(TAG, "Replacing mediaset " + mediaSet.mName + " id " + setIdToUse + " current Id " + mediaSet.mId);
             if (setIdToUse == CAMERA_BUCKET_ID) {
                 mediaSet.mName = CAMERA_STRING;
             } else if (setIdToUse == DOWNLOAD_BUCKET_ID) {
index a72a9c6..f905ed0 100644 (file)
@@ -704,9 +704,11 @@ public final class MediaFeed implements Runnable {
         ArrayList<MediaSet> mediaSets = mMediaSets;
         int numSets = mediaSets.size();
         for (int i = 0; i < numSets; ++i) {
-            if (mediaSets.get(i).mId == setId) {
-                MediaSet thisSet = mediaSets.get(i);
+               final MediaSet thisSet = mediaSets.get(i);
+            if (thisSet.mId == setId) {
                 mediaSet.mName = thisSet.mName;
+                mediaSet.mHasImages = thisSet.mHasImages;
+                mediaSet.mHasVideos = thisSet.mHasVideos;
                 mediaSets.set(i, mediaSet);
                 break;
             }
index e3b9f87..868a23e 100644 (file)
@@ -42,7 +42,7 @@ public final class PicasaDataSource implements DataSource {
         for (int i = 0; i < numAccounts; ++i) {
             Account account = accounts[i];
             boolean isEnabled = ContentResolver.getSyncAutomatically(account, PicasaContentProvider.AUTHORITY);
-            String username = account.name;
+            String username = account.name.toLowerCase();
             if (username.contains("@gmail.") || username.contains("@googlemail.")) {
                 // Strip the domain from GMail accounts for canonicalization. TODO: is there an official way?
                 username = username.substring(0, username.indexOf('@'));
@@ -109,7 +109,8 @@ public final class PicasaDataSource implements DataSource {
                 final ArrayList<MediaSet> picasaSets = new ArrayList<MediaSet>(numAlbums);
                 do {
                     albumSchema.cursorToObject(cursor, album);
-                    final Boolean accountEnabledObj = accountsEnabled.get(album.user);
+                    String userLowerCase = album.user.toLowerCase();
+                    final Boolean accountEnabledObj = accountsEnabled.get(userLowerCase);
                     final boolean accountEnabled = (accountEnabledObj == null) ? false : accountEnabledObj.booleanValue();
                     if (accountEnabled) {
                         mediaSet = feed.getMediaSet(album.id);