OSDN Git Service

Updates to 3D gallery source.
authorDave Sparks <davidsparks@android.com>
Wed, 2 Dec 2009 15:57:34 +0000 (07:57 -0800)
committerDave Sparks <davidsparks@android.com>
Wed, 2 Dec 2009 15:57:34 +0000 (07:57 -0800)
20 files changed:
src.zip [new file with mode: 0644]
src/com/cooliris/cache/CacheService.java
src/com/cooliris/media/BackgroundLayer.java
src/com/cooliris/media/CanvasTexture.java
src/com/cooliris/media/DetailMode.java
src/com/cooliris/media/Gallery.java
src/com/cooliris/media/GridDrawManager.java
src/com/cooliris/media/GridInputProcessor.java
src/com/cooliris/media/GridLayer.java
src/com/cooliris/media/HudLayer.java
src/com/cooliris/media/MediaFeed.java
src/com/cooliris/media/MediaItemTexture.java
src/com/cooliris/media/MediaSet.java
src/com/cooliris/media/PathBarLayer.java
src/com/cooliris/media/PicasaDataSource.java
src/com/cooliris/media/PopupMenu.java
src/com/cooliris/media/ReverseGeocoder.java
src/com/cooliris/media/SingleDataSource.java
src/com/cooliris/media/TimeBar.java
src/com/cooliris/wallpaper/Slideshow.java

diff --git a/src.zip b/src.zip
new file mode 100644 (file)
index 0000000..ddc6415
Binary files /dev/null and b/src.zip differ
index 864ac97..f3e610f 100644 (file)
@@ -395,7 +395,7 @@ public final class CacheService extends IntentService {
     public static final void populateMediaItemFromCursor(final MediaItem item, final ContentResolver cr, final Cursor cursor,
             final String baseUri) {
         item.mId = cursor.getLong(CacheService.MEDIA_ID_INDEX);
-        //item.mCaption = cursor.getString(CacheService.MEDIA_CAPTION_INDEX);
+        // item.mCaption = cursor.getString(CacheService.MEDIA_CAPTION_INDEX);
         item.mMimeType = cursor.getString(CacheService.MEDIA_MIME_TYPE_INDEX);
         item.mLatitude = cursor.getDouble(CacheService.MEDIA_LATITUDE_INDEX);
         item.mLongitude = cursor.getDouble(CacheService.MEDIA_LONGITUDE_INDEX);
@@ -551,7 +551,6 @@ public final class CacheService extends IntentService {
         if (origId == Shared.INVALID) {
             return null;
         }
-        Log.i(TAG, "Building thumbnail for item " + origId);
         try {
             Bitmap bitmap = null;
             Thread.sleep(1);
@@ -588,7 +587,6 @@ public final class CacheService extends IntentService {
                 return null;
             }
             final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight);
-            Log.i(TAG, "Generated thumbnail for item " + origId);
             return retVal;
         } catch (InterruptedException e) {
             return null;
@@ -850,32 +848,36 @@ public final class CacheService extends IntentService {
         cursors[0] = cursorImages;
         cursors[1] = cursorVideos;
         final SortCursor sortCursor = new SortCursor(cursors, Images.ImageColumns.BUCKET_DISPLAY_NAME, SortCursor.TYPE_STRING, true);
-
-        if (sortCursor != null && sortCursor.moveToFirst()) {
-            sets.ensureCapacity(sortCursor.getCount());
-            acceleratedSets = new LongSparseArray<MediaSet>(sortCursor.getCount());
-            MediaSet cameraSet = new MediaSet();
-            cameraSet.mId = LocalDataSource.CAMERA_BUCKET_ID;
-            cameraSet.mName = context.getResources().getString(R.string.camera);
-            sets.add(cameraSet);
-            acceleratedSets.put(cameraSet.mId, cameraSet);
-            do {
-                if (Thread.interrupted()) {
-                    return;
-                }
-                long setId = sortCursor.getLong(BUCKET_ID_INDEX);
-                MediaSet mediaSet = findSet(setId, acceleratedSets);
-                if (mediaSet == null) {
-                    mediaSet = new MediaSet();
-                    mediaSet.mId = setId;
-                    mediaSet.mName = sortCursor.getString(BUCKET_NAME_INDEX);
-                    sets.add(mediaSet);
-                    acceleratedSets.put(setId, mediaSet);
-                }
-                mediaSet.mHasImages |= (sortCursor.getCurrentCursorIndex() == 0);
-                mediaSet.mHasVideos |= (sortCursor.getCurrentCursorIndex() == 1);
-            } while (sortCursor.moveToNext());
-            sortCursor.close();
+        try {
+            if (sortCursor != null && sortCursor.moveToFirst()) {
+                sets.ensureCapacity(sortCursor.getCount());
+                acceleratedSets = new LongSparseArray<MediaSet>(sortCursor.getCount());
+                MediaSet cameraSet = new MediaSet();
+                cameraSet.mId = LocalDataSource.CAMERA_BUCKET_ID;
+                cameraSet.mName = context.getResources().getString(R.string.camera);
+                sets.add(cameraSet);
+                acceleratedSets.put(cameraSet.mId, cameraSet);
+                do {
+                    if (Thread.interrupted()) {
+                        return;
+                    }
+                    long setId = sortCursor.getLong(BUCKET_ID_INDEX);
+                    MediaSet mediaSet = findSet(setId, acceleratedSets);
+                    if (mediaSet == null) {
+                        mediaSet = new MediaSet();
+                        mediaSet.mId = setId;
+                        mediaSet.mName = sortCursor.getString(BUCKET_NAME_INDEX);
+                        sets.add(mediaSet);
+                        acceleratedSets.put(setId, mediaSet);
+                    }
+                    mediaSet.mHasImages |= (sortCursor.getCurrentCursorIndex() == 0);
+                    mediaSet.mHasVideos |= (sortCursor.getCurrentCursorIndex() == 1);
+                } while (sortCursor.moveToNext());
+                sortCursor.close();
+            }
+        } finally {
+            if (sortCursor != null)
+                sortCursor.close();
         }
 
         sAlbumCache.put(ALBUM_CACHE_INCOMPLETE_INDEX, sDummyData);
@@ -951,33 +953,36 @@ public final class CacheService extends IntentService {
         if (Thread.interrupted()) {
             return;
         }
-        
-        if (sortCursor != null && sortCursor.moveToFirst()) {
-            final int count = sortCursor.getCount();
-            final int numSets = sets.size();
-            final int approximateCountPerSet = count / numSets;
-            for (int i = 0; i < numSets; ++i) {
-                final MediaSet set = sets.get(i);
-                set.getItems().clear();
-                set.setNumExpectedItems(approximateCountPerSet);
-            }
-            do {
-                if (Thread.interrupted()) {
-                    return;
-                }
-                final MediaItem item = new MediaItem();
-                final boolean isVideo = (sortCursor.getCurrentCursorIndex() == 1);
-                if (isVideo) {
-                    populateVideoItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_VIDEOS);
-                } else {
-                    populateMediaItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_IMAGES);
-                }
-                final long setId = sortCursor.getLong(MEDIA_BUCKET_ID_INDEX);
-                final MediaSet set = findSet(setId, acceleratedSets);
-                if (set != null) {
-                    set.getItems().add(item);
+        try {
+            if (sortCursor != null && sortCursor.moveToFirst()) {
+                final int count = sortCursor.getCount();
+                final int numSets = sets.size();
+                final int approximateCountPerSet = count / numSets;
+                for (int i = 0; i < numSets; ++i) {
+                    final MediaSet set = sets.get(i);
+                    set.getItems().clear();
+                    set.setNumExpectedItems(approximateCountPerSet);
                 }
-            } while (sortCursor.moveToNext());
+                do {
+                    if (Thread.interrupted()) {
+                        return;
+                    }
+                    final MediaItem item = new MediaItem();
+                    final boolean isVideo = (sortCursor.getCurrentCursorIndex() == 1);
+                    if (isVideo) {
+                        populateVideoItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_VIDEOS);
+                    } else {
+                        populateMediaItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_IMAGES);
+                    }
+                    final long setId = sortCursor.getLong(MEDIA_BUCKET_ID_INDEX);
+                    final MediaSet set = findSet(setId, acceleratedSets);
+                    if (set != null) {
+                        set.getItems().add(item);
+                    }
+                } while (sortCursor.moveToNext());
+            }
+        } finally {
+            if (sortCursor != null) sortCursor.close();
         }
         if (sets.size() > 0) {
             writeItemsToCache(sets);
index 6eba7ee..234e916 100644 (file)
@@ -94,7 +94,7 @@ public class BackgroundLayer extends Layer {
             view.bind(mFallbackBackground);
         } else {
             Texture texture = anchorTexture.getTexture();
-            if (texture.isLoaded()) {
+            if (texture != null && texture.isLoaded()) {
                 mFallbackBackground = texture;
             }
         }
index 27baaa4..a881eef 100644 (file)
@@ -21,6 +21,7 @@ public abstract class CanvasTexture {
     private Bitmap mBitmap = null;
     private boolean mNeedsDraw = false;
     private boolean mNeedsResize = false;
+    private GL11 mCachedGL = null;
 
     public CanvasTexture(Bitmap.Config bitmapConfig) {
         mBitmapConfig = bitmapConfig;
@@ -63,6 +64,10 @@ public abstract class CanvasTexture {
 
     // This code seems largely a dup of CanvasLayer.
     public boolean bind(GL11 gl) {
+        if (mCachedGL != gl) {
+            mCachedGL = gl;
+            resetTexture();
+        }
         int width = (int) mWidth;
         int height = (int) mHeight;
         int textureId = mTextureId;
@@ -110,9 +115,11 @@ public abstract class CanvasTexture {
                 // Recycle the existing bitmap and create a new one.
                 if (bitmap != null)
                     bitmap.recycle();
-                bitmap = Bitmap.createBitmap(textureWidth, textureHeight, mBitmapConfig);
-                canvas.setBitmap(bitmap);
-                mBitmap = bitmap;
+                if (textureWidth > 0 && textureHeight > 0) {
+                    bitmap = Bitmap.createBitmap(textureWidth, textureHeight, mBitmapConfig);
+                    canvas.setBitmap(bitmap);
+                    mBitmap = bitmap;
+                }
             }
         }
 
@@ -147,7 +154,7 @@ public abstract class CanvasTexture {
             float height = mHeight;
 
             // Apply scale transform if not identity.
-            if (scale != 1) {  // CR: 1.0f
+            if (scale != 1) { // CR: 1.0f
                 float originX = x + anchorX * width;
                 float originY = y + anchorY * height;
                 width *= scale;
@@ -157,7 +164,7 @@ public abstract class CanvasTexture {
             }
 
             // Set alpha if needed.
-            if (alpha != 1f) {  // CR: 1.0f
+            if (alpha != 1f) { // CR: 1.0f
                 view.setAlpha(alpha);
             }
             view.draw2D(x, y, 0, width, height);
index 82703ac..cf78a58 100644 (file)
@@ -5,7 +5,7 @@ import java.util.ArrayList;
 import java.util.Date;
 
 import android.content.Context;
-import android.content.res.Resources;
+import android.content.res.Resources;;
 
 public final class DetailMode {
     public static CharSequence[] populateDetailModeStrings(Context context, ArrayList<MediaBucket> buckets) {
@@ -64,11 +64,9 @@ public final class DetailMode {
         } else {
             strings[1] = Integer.toString(numItems) + " " + resources.getString(R.string.items_selected);
         }
-
-        DateFormat dateTimeFormat =
-            DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
-                                           DateFormat.SHORT);
-
+        
+        DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.SHORT);
+        
         // Start and end times of the selected items.
         if (selectedItemsSet.areTimestampsAvailable()) {
             long minTimestamp = selectedItemsSet.mMinTimestamp;
@@ -87,7 +85,7 @@ public final class DetailMode {
                 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[3] = 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);
@@ -118,11 +116,9 @@ public final class DetailMode {
         CharSequence[] strings = new CharSequence[5];
         strings[0] = resources.getString(R.string.title) + ": " + item.mCaption;
         strings[1] = resources.getString(R.string.type) + ": " + item.getDisplayMimeType();
-
-        DateFormat dateTimeFormat =
-            DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
-                                           DateFormat.SHORT);
-
+        
+        DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.SHORT);
+        
         if (item.isDateTakenValid()) {
             long dateTaken = item.mDateTakenInMs;
             if (item.isPicassaItem()) {
@@ -135,7 +131,7 @@ public final class DetailMode {
                 dateAdded -= Gallery.CURRENT_TIME_ZONE.getOffset(dateAdded);
             }
             // TODO: Make this added_on as soon as translations are ready.
-            //strings[2] = resources.getString(R.string.added_on) + ": " + dateTimeFormat.format(new Date(dateAdded));
+            //strings[2] = resources.getString(R.string.added_on) + ": " + DateFormat.format("h:mmaa MMM dd yyyy", dateAdded);
             strings[2] = resources.getString(R.string.taken_on) + ": " + dateTimeFormat.format(new Date(dateAdded));
         } else {
             strings[2] = resources.getString(R.string.taken_on) + ": " + resources.getString(R.string.date_unknown);
@@ -154,4 +150,4 @@ public final class DetailMode {
         strings[4] = resources.getString(R.string.location) + ": " + locationString;
         return strings;
     }
-}
+}
\ No newline at end of file
index 63d6005..2a2a170 100644 (file)
@@ -6,12 +6,15 @@ import java.util.TimeZone;
 
 import android.app.Activity;
 import android.app.ProgressDialog;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
 import android.provider.MediaStore.Images;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -37,15 +40,25 @@ public final class Gallery extends Activity {
     private ReverseGeocoder mReverseGeocoder;
     private boolean mPause;
     private MediaScannerConnection mConnection;
+    private WakeLock mWakeLock;
     private static final boolean TEST_WALLPAPER = false;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        final boolean imageManagerHasStorage = ImageManager.quickHasStorage();
         if (TEST_WALLPAPER || (isViewIntent() && getIntent().getData().equals(Images.Media.EXTERNAL_CONTENT_URI))) {
-            Slideshow slideshow = new Slideshow(this);
-            slideshow.setDataSource(new RandomDataSource());
-            setContentView(slideshow);
+            if (!imageManagerHasStorage) {
+                Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
+                finish();
+            } else {
+                PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+                mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow.All");
+                mWakeLock.acquire();
+                Slideshow slideshow = new Slideshow(this);
+                slideshow.setDataSource(new RandomDataSource());
+                setContentView(slideshow);
+            }
             return;
         }
         boolean isCacheReady = CacheService.isCacheReady(false);
@@ -61,7 +74,6 @@ public final class Gallery extends Activity {
                 mRenderView);
         mRenderView.setRootLayer(mGridLayer);
         setContentView(mRenderView);
-        final boolean imageManagerHasStorage = ImageManager.quickHasStorage();
         if (!isPickIntent() && !isViewIntent()) {
             PicasaDataSource picasaDataSource = new PicasaDataSource(this);
             if (imageManagerHasStorage) {
@@ -195,6 +207,12 @@ public final class Gallery extends Activity {
             }
             mGridLayer.shutdown();
         }
+        if (mWakeLock != null) {
+            if (mWakeLock.isHeld()) {
+                mWakeLock.release();
+            }
+            mWakeLock = null;
+        }
         if (mReverseGeocoder != null)
             mReverseGeocoder.shutdown();
         if (mRenderView != null) {
index 1626896..94c6627 100644 (file)
@@ -296,7 +296,7 @@ public final class GridDrawManager {
                             mSelectedMixRatio.animateValue(1f, 0.75f, view.getFrameTime());
                         }
                     }
-                    if (mCamera.isAnimating()) {
+                    if (mCamera.isAnimating() || slideshowMode) {
                         if (!slideshowMode && skipPrevious && i == -1) {
                             continue;
                         }
index a8943a7..c7050cb 100644 (file)
@@ -559,7 +559,11 @@ public final class GridInputProcessor implements GestureDetector.OnGestureListen
                 } else {
                     // We stop any slideshow.
                     HudLayer hud = layer.getHud();
-                    layer.endSlideshow();
+                    if (layer.inSlideShowMode()) {
+                        layer.endSlideshow();
+                    } else {
+                        hud.setAlpha(1.0f - hud.getAlpha());
+                    }
                     if (hud.getMode() == HudLayer.MODE_SELECT) {
                         hud.setAlpha(1.0f);
                     }
@@ -657,10 +661,11 @@ public final class GridInputProcessor implements GestureDetector.OnGestureListen
     }
 
     private void vibrateShort() {
-        mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+        // As per request by Google, this line disables vibration.
+        //mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
     }
 
     private void vibrateLong() {
-        mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+        //mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
     }
 }
index cf9830e..dc2b09f 100644 (file)
@@ -106,6 +106,7 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
     private int mStartMemoryRange;
     private int mFramesDirty;
     private String mRequestFocusContentUri;
+    private int mFrameCount;
 
     public GridLayer(Context context, int itemWidth, int itemHeight, LayoutInterface layoutInterface, RenderView view) {
         mBackground = new BackgroundLayer(this);
@@ -164,12 +165,10 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
             mMediaFeed.shutdown();
         }
         mContext = null;
-        mInputProcessor = null;
         mBackground = null;
         sBucketList.clear();
         mCameraManager = null;
         mDrawManager = null;
-        sHud.shutDown();
         mView = null;
     }
 
@@ -535,6 +534,7 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
         boolean dirty = mDrawManager.update(timeElapsed);
         dirty |= mSlideshowMode;
         dirty |= mFramesDirty > 0;
+        ++mFrameCount;
         if (mFramesDirty > 0) {
             --mFramesDirty;
         }
@@ -961,7 +961,12 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
         if (slotIndex == Shared.INVALID) {
             slotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
         }
-        return sDisplayItems[(slotIndex - sBufferedVisibleRange.begin) * MAX_ITEMS_PER_SLOT];
+        int index = (slotIndex - sBufferedVisibleRange.begin) * MAX_ITEMS_PER_SLOT;
+        if (index >= 0 && index < MAX_ITEMS_DRAWABLE) {
+            return sDisplayItems[index];
+        } else {
+            return null;
+        }
     }
 
     public DisplayItem getAnchorDisplayItem(int type) {
@@ -1390,7 +1395,8 @@ public final class GridLayer extends RootLayer implements MediaFeed.Listener, Ti
                         }
                         if (sHud.getAlpha() == 1.0f) {
                         disableLocationFiltering();
-                        mInputProcessor.clearSelection();
+                        if (mInputProcessor != null)
+                            mInputProcessor.clearSelection();
                         setState(STATE_GRID_VIEW);
                         } else {
                             sHud.setAlpha(1.0f);
index a67272f..e2d1bef 100644 (file)
@@ -15,7 +15,6 @@ import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.net.Uri;
 import android.util.FloatMath;
-import android.util.Log;
 import android.view.MotionEvent;
 
 import com.cooliris.media.MenuBar.Menu;
@@ -752,10 +751,6 @@ public final class HudLayer extends Layer {
 
     }
 
-    public void shutDown() {
-        
-    }
-
     public void enterSelectionMode() {
         setAlpha(1.0f);
         setMode(HudLayer.MODE_SELECT);
index 71c00ed..b10187a 100644 (file)
@@ -516,10 +516,12 @@ public final class MediaFeed implements Runnable {
                         if (mInClusteringMode && mClusterSets != null) {
                             requestedItems = 0;
                             MediaClustering clustering = mClusterSets.get(mediaSets.get(expandedSetIndex));
-                            ArrayList<Cluster> clusters = clustering.getClustersForDisplay();
-                            int numClusters = clusters.size();
-                            for (int i = 0; i < numClusters; i++) {
-                                requestedItems += clusters.get(i).getNumExpectedItems();
+                            if (clustering != null) {
+                                ArrayList<Cluster> clusters = clustering.getClustersForDisplay();
+                                int numClusters = clusters.size();
+                                for (int i = 0; i < numClusters; i++) {
+                                    requestedItems += clusters.get(i).getNumExpectedItems();
+                                }
                             }
                         }
                         MediaSet set = mediaSets.get(expandedSetIndex);
index c312cf4..9d0b198 100644 (file)
@@ -46,7 +46,7 @@ public final class MediaItemTexture extends Texture {
         if (config != null && parentMediaSet != null && parentMediaSet.mDataSource != null) {
             cache = parentMediaSet.mDataSource.getThumbnailCache();
             if (cache == LocalDataSource.sThumbnailCache) {
-                if (item.mMimeType.contains("video")) {
+                if (item.mMimeType != null && item.mMimeType.contains("video")) {
                     cache = LocalDataSource.sThumbnailCacheVideo;
                 }
             }
index 4812ef9..56c3893 100644 (file)
@@ -131,7 +131,7 @@ public class MediaSet {
         mTitleString = mName + size;
         if (truncateTitle) {
             int length = mName.length();
-            mTruncTitleString = (length > 16) ? mName.substring(0, 12) + "\u2026" + mName.substring(length - 4, length) + size : mName + size;
+            mTruncTitleString = (length > 16) ? mName.substring(0, 12) + "..." + mName.substring(length - 4, length) + size : mName + size;
             mNoCountTitleString = mName;
         } else {
             mTruncTitleString = mTitleString;
index 3b2198f..5a1e7c8 100644 (file)
@@ -97,7 +97,7 @@ public final class PathBarLayer extends Layer {
             if (origString != null) {
                 label = origString.substring(0, StringTexture.lengthToFit(sPathFormat.fontSize, widthLeft, typeface, origString));
                 if (label.length() != origString.length()) {
-                    label += "\u2026";
+                    label += "...";
                 }
             }
             this.texture = new StringTexture(label, sPathFormat);
index 22aca3c..0bd34ae 100644 (file)
@@ -1,7 +1,9 @@
 package com.cooliris.media;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 
+import android.accounts.Account;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -28,6 +30,7 @@ public final class PicasaDataSource implements DataSource {
     private ContentProviderClient mProviderClient;
     private final Context mContext;
     private ContentObserver mAlbumObserver;
+    private HashMap<String, Boolean> mAccountEnabled = new HashMap<String, Boolean>();
 
     public PicasaDataSource(Context context) {
         mContext = context;
@@ -39,10 +42,10 @@ public final class PicasaDataSource implements DataSource {
         }
         // Force permission dialog to be displayed if necessary. TODO: remove this after signed by Google.
         PicasaApi.getAccounts(mContext);
-        
+
         // Ensure that users are up to date. TODO: also listen for accounts changed broadcast.
         PicasaService.requestSync(mContext, PicasaService.TYPE_USERS_ALBUMS, 0);
-        Handler handler = ((Gallery)mContext).getHandler();
+        Handler handler = ((Gallery) mContext).getHandler();
         ContentObserver albumObserver = new ContentObserver(handler) {
             public void onChange(boolean selfChange) {
                 loadMediaSetsIntoFeed(feed, true);
@@ -50,13 +53,13 @@ public final class PicasaDataSource implements DataSource {
         };
         mAlbumObserver = albumObserver;
         loadMediaSetsIntoFeed(feed, true);
-        
+
         // Start listening.
         ContentResolver cr = mContext.getContentResolver();
         cr.registerContentObserver(PicasaContentProvider.ALBUMS_URI, false, mAlbumObserver);
         cr.registerContentObserver(PicasaContentProvider.PHOTOS_URI, false, mAlbumObserver);
     }
+
     public void shutdown() {
         if (mAlbumObserver != null) {
             ContentResolver cr = mContext.getContentResolver();
@@ -74,6 +77,18 @@ public final class PicasaDataSource implements DataSource {
     }
 
     protected void loadMediaSetsIntoFeed(final MediaFeed feed, boolean sync) {
+        Account[] accounts = PicasaApi.getAccounts(mContext);
+        int numAccounts = accounts.length;
+        for (int i = 0; i < numAccounts; ++i) {
+            Account account = accounts[i];
+            boolean isEnabled = ContentResolver.getSyncAutomatically(account, PicasaContentProvider.AUTHORITY);
+            String username = account.name;
+            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('@'));
+            }
+            mAccountEnabled.put(username, new Boolean(isEnabled));
+        }
         ContentProviderClient client = mProviderClient;
         if (client == null)
             return;
@@ -88,18 +103,22 @@ public final class PicasaDataSource implements DataSource {
                 ArrayList<MediaSet> picasaSets = new ArrayList<MediaSet>(numAlbums);
                 do {
                     albumSchema.cursorToObject(cursor, album);
-                    mediaSet = feed.getMediaSet(album.id);
-                    if (mediaSet == null) {
-                        mediaSet = feed.addMediaSet(album.id, this);
-                        mediaSet.mName = album.title;
-                        mediaSet.mEditUri = album.editUri;
-                        mediaSet.generateTitle(true);
-                    } else {
-                        mediaSet.setNumExpectedItems(album.numPhotos);
+                    Boolean accountEnabledObj = mAccountEnabled.get(album.user);
+                    boolean accountEnabled = (accountEnabledObj == null) ? false : accountEnabledObj.booleanValue();
+                    if (accountEnabled) {
+                        mediaSet = feed.getMediaSet(album.id);
+                        if (mediaSet == null) {
+                            mediaSet = feed.addMediaSet(album.id, this);
+                            mediaSet.mName = album.title;
+                            mediaSet.mEditUri = album.editUri;
+                            mediaSet.generateTitle(true);
+                        } else {
+                            mediaSet.setNumExpectedItems(album.numPhotos);
+                        }
+                        mediaSet.mPicasaAlbumId = album.id;
+                        mediaSet.mSyncPending = album.photosDirty;
+                        picasaSets.add(mediaSet);
                     }
-                    mediaSet.mPicasaAlbumId = album.id;
-                    mediaSet.mSyncPending = album.photosDirty;
-                    picasaSets.add(mediaSet);
                 } while (cursor.moveToNext());
             }
             cursor.close();
@@ -189,7 +208,7 @@ public final class PicasaDataSource implements DataSource {
                         for (int j = 0, numItems = items.size(); j != numItems; ++j) {
                             MediaItem item = items.get(j);
                             if (item != null) {
-                                String itemUri = PicasaContentProvider.PHOTOS_URI + "/" + item.mId; 
+                                String itemUri = PicasaContentProvider.PHOTOS_URI + "/" + item.mId;
                                 client.delete(Uri.parse(itemUri), null, null);
                             }
                         }
index f200061..f51e7b9 100644 (file)
@@ -31,7 +31,7 @@ public final class PopupMenu extends Layer {
     private static final int ICON_TITLE_MIN_WIDTH = 100;
     private static final IconTitleDrawable.Config ICON_TITLE_CONFIG;
 
-    private final PopupTexture mPopupTexture;
+    private PopupTexture mPopupTexture;
     private Listener mListener = null;
     private Option[] mOptions = {};
     private boolean mNeedsLayout = false;
@@ -45,7 +45,8 @@ public final class PopupMenu extends Layer {
         paint.setTextSize(17f * Gallery.PIXEL_DENSITY);
         paint.setColor(0xffffffff);
         paint.setAntiAlias(true);
-        ICON_TITLE_CONFIG = new IconTitleDrawable.Config((int)(45 * Gallery.PIXEL_DENSITY), (int)(34 * Gallery.PIXEL_DENSITY), paint);
+        ICON_TITLE_CONFIG = new IconTitleDrawable.Config((int) (45 * Gallery.PIXEL_DENSITY), (int) (34 * Gallery.PIXEL_DENSITY),
+                paint);
         SRC_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
     }
 
@@ -70,8 +71,8 @@ public final class PopupMenu extends Layer {
             layout();
         }
         // Try to center the popup over the target point.
-        int width = (int)mWidth;
-        int height = (int)mHeight;
+        int width = (int) mWidth;
+        int height = (int) mHeight;
         int widthOver2 = width / 2;
         int x = pointX - widthOver2;
         int y = pointY + POPUP_Y_OFFSET - height;
@@ -101,7 +102,7 @@ public final class PopupMenu extends Layer {
             mShow = false;
             mSelectedItem = -1;
         }
-        
+
     }
 
     @Override
@@ -115,13 +116,12 @@ public final class PopupMenu extends Layer {
     @Override
     protected void onSizeChanged() {
         super.onSizeChanged();
-        mPopupTexture.setSize((int)mWidth, (int)mHeight);
+        mPopupTexture.setSize((int) mWidth, (int) mHeight);
     }
 
     @Override
     protected void onSurfaceCreated(RenderView view, GL11 gl) {
         close(false);
-        mPopupTexture.resetTexture();
     }
 
     @Override
@@ -155,11 +155,11 @@ public final class PopupMenu extends Layer {
             }
         }
     }
-    
+
     @Override
     public boolean update(RenderView view, float timeElapsed) {
         return (mShowAnim.getTimeRemaining(SystemClock.uptimeMillis()) > 0);
-     }
+    }
 
     @Override
     public void renderBlended(RenderView view, GL11 gl) {
@@ -173,7 +173,6 @@ public final class PopupMenu extends Layer {
         // Draw the selection menu with the show animation.
         int x = (int) mX;
         int y = (int) mY;
-
         if (show && showRatio < 1f) {
             // Animate the scale as well for the open animation.
             float scale;
@@ -193,6 +192,7 @@ public final class PopupMenu extends Layer {
                 view.resetColor();
             }
         }
+
     }
 
     private void layout() {
@@ -202,7 +202,7 @@ public final class PopupMenu extends Layer {
         // Measure the menu options.
         Option[] options = mOptions;
         int numOptions = options.length;
-        int maxWidth = (int)(ICON_TITLE_MIN_WIDTH * Gallery.PIXEL_DENSITY);
+        int maxWidth = (int) (ICON_TITLE_MIN_WIDTH * Gallery.PIXEL_DENSITY);
         for (int i = 0; i != numOptions; ++i) {
             Option option = options[i];
             IconTitleDrawable drawable = option.mDrawable;
@@ -217,9 +217,9 @@ public final class PopupMenu extends Layer {
         }
 
         // Layout the menu options.
-        int rowHeight = (int)(mRowHeight * Gallery.PIXEL_DENSITY);
-        int left = (int)(PADDING_LEFT * Gallery.PIXEL_DENSITY);
-        int top = (int)(PADDING_TOP * Gallery.PIXEL_DENSITY);
+        int rowHeight = (int) (mRowHeight * Gallery.PIXEL_DENSITY);
+        int left = (int) (PADDING_LEFT * Gallery.PIXEL_DENSITY);
+        int top = (int) (PADDING_TOP * Gallery.PIXEL_DENSITY);
         int right = left + maxWidth;
         for (int i = 0; i != numOptions; ++i) {
             Option option = options[i];
@@ -231,7 +231,7 @@ public final class PopupMenu extends Layer {
 
         // Resize the popup menu.
         setSize(right + PADDING_RIGHT * Gallery.PIXEL_DENSITY, top + PADDING_BOTTOM * Gallery.PIXEL_DENSITY);
-        
+
     }
 
     private int hitTestOptions(int x, int y) {
@@ -288,7 +288,7 @@ public final class PopupMenu extends Layer {
 
         @Override
         protected void onSizeChanged() {
-            mBackgroundRect.set(0, 0, getWidth(), getHeight() - (int)(POPUP_TRIANGLE_EXTRA_HEIGHT * Gallery.PIXEL_DENSITY));
+            mBackgroundRect.set(0, 0, getWidth(), getHeight() - (int) (POPUP_TRIANGLE_EXTRA_HEIGHT * Gallery.PIXEL_DENSITY));
         }
 
         @Override
index 41b18c1..b490987 100644 (file)
@@ -317,9 +317,9 @@ public final class ReverseGeocoder extends Thread {
                     if (country == null) {
                         locale = new Locale(language);
                     } else if (variant == null) {
-                        locale = new Locale(country, language);
+                        locale = new Locale(language, country);
                     } else {
-                        locale = new Locale(country, language, variant);
+                        locale = new Locale(language, country, variant);
                     }
                 }
                 if (!locale.getLanguage().equals(Locale.getDefault().getLanguage())) {
index 6d8e0d4..b0ae940 100644 (file)
@@ -89,9 +89,27 @@ public class SingleDataSource implements DataSource {
                     parentSet.generateTitle(true);
                 }
             } else if (mUri.startsWith("file://")) {
-                MediaItem newItem = LocalDataSource.createMediaItemFromFileUri(mContext, mUri);
-                if (newItem != null)
+                MediaItem newItem = null;
+                int numRetries = 3;
+                do {
+                    newItem = LocalDataSource.createMediaItemFromFileUri(mContext, mUri);
+                    if (newItem == null) {
+                        --numRetries;
+                        try {
+                            Thread.sleep(300);
+                        } catch (InterruptedException e) {
+                            ;
+                        }
+                    }
+                } while (newItem == null && numRetries >= 0);
+                if (newItem != null) {
                     item = newItem;
+                } else {
+                    item.mContentUri = mUri;
+                    item.mThumbnailUri = mUri;
+                    item.mScreennailUri = mUri;
+                    feed.setSingleImageMode(true);
+                }
             } else {
                 item.mContentUri = mUri;
                 item.mThumbnailUri = mUri;
index c85be4c..1fc4238 100644 (file)
@@ -47,7 +47,7 @@ public final class TimeBar extends Layer implements MediaFeed.Listener {
     private final StringTexture[] mMonthLabels = new StringTexture[12];
     private final StringTexture[] mDayLabels = new StringTexture[32];
     private final StringTexture[] mOpaqueDayLabels = new StringTexture[32];
-    private final StringTexture mDot = new StringTexture("\u2022");
+    private final StringTexture mDot = new StringTexture("¥");
     private final HashMap<MediaItem, Marker> mTracker = new HashMap<MediaItem, Marker>(1024);
     private int mState;
     private float mTextAlpha = 0.0f;
@@ -87,6 +87,7 @@ public final class TimeBar extends Layer implements MediaFeed.Listener {
             mOpaqueDayLabels[i] = new StringTexture(Integer.toString(i), mMonthYearFormat);
         }
         mDateUnknown = new StringTexture(context.getResources().getString(R.string.date_unknown), mMonthYearFormat);
+        mBackgroundTexture = null;
     }
 
     public void setListener(Listener listener) {
index fdd3a17..376a739 100644 (file)
@@ -24,7 +24,7 @@ public class Slideshow extends SurfaceView implements SurfaceHolder.Callback {
         holder.addCallback(this);
     }
 
-    public static final int SLIDESHOW_DURATION = 5000;
+    public static final int SLIDESHOW_DURATION = 2000;
 
     public interface DataSource {
         /**
@@ -126,7 +126,6 @@ public class Slideshow extends SurfaceView implements SurfaceHolder.Callback {
                         performUpdate(mQueuedFrameRect, sQueuedGrow, delta);
                         if (alpha >= 1.0f) {
                             // We switch the image.
-                            mBitmap.recycle();
                             mRect = mQueuedRect;
                             mBitmap = mQueuedBitmap;
                             mFrameRect =  mQueuedFrameRect;
@@ -156,7 +155,7 @@ public class Slideshow extends SurfaceView implements SurfaceHolder.Callback {
 
     private void performUpdate(RectF rect, Vector3f grow, long delta) {
         float timeElapsed = ((float)(delta)) / 1000.0f;
-        float amountToGrowX = timeElapsed * (rect.width() / 30.0f);
+        float amountToGrowX = timeElapsed * (rect.width() / 15.0f);
         float amountToGrowY = amountToGrowX * (rect.height() / rect.width());
         rect.top -= amountToGrowY * grow.x;
         rect.left -= amountToGrowX * grow.y;