diff options
author | Sascha Haeberling <haeberling@google.com> | 2013-08-06 14:31:52 -0700 |
---|---|---|
committer | Sascha Haeberling <haeberling@google.com> | 2013-08-06 14:58:07 -0700 |
commit | 37f3611bbdc787c996a99894dcef7d8fb77e3f7c (patch) | |
tree | 4dc08a60a543dc4d2b0672a8c0cc4efdc30b52ad /src/com/android/camera/data | |
parent | 8fe71f31bc8ab1b634566a3060e041e22e9b2e41 (diff) | |
download | android_packages_apps_Snap-37f3611bbdc787c996a99894dcef7d8fb77e3f7c.tar.gz android_packages_apps_Snap-37f3611bbdc787c996a99894dcef7d8fb77e3f7c.tar.bz2 android_packages_apps_Snap-37f3611bbdc787c996a99894dcef7d8fb77e3f7c.zip |
This adds the following four CLs to Camera2:
http://ag/339319
http://ag/338974
http://ag/338401
http://ag/324149
Adapted to work in Camera2 and adding a .gitignore so that temporary
Eclipse files and folders are not submitted.
Change-Id: I40295c7f0139f76270c44f0ca395c0574a288569
Diffstat (limited to 'src/com/android/camera/data')
-rw-r--r-- | src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java | 10 | ||||
-rw-r--r-- | src/com/android/camera/data/CameraDataAdapter.java | 174 | ||||
-rw-r--r-- | src/com/android/camera/data/FixedFirstDataAdapter.java | 45 | ||||
-rw-r--r-- | src/com/android/camera/data/FixedLastDataAdapter.java | 57 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalData.java | 128 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalDataAdapter.java | 27 |
6 files changed, 330 insertions, 111 deletions
diff --git a/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java b/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java index 66c55850a..5df87f5a8 100644 --- a/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java +++ b/src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java @@ -74,6 +74,11 @@ public abstract class AbstractLocalDataAdapterWrapper implements LocalDataAdapte } @Override + public void insertData(LocalData data) { + mAdapter.insertData(data); + } + + @Override public void flush() { mAdapter.flush(); } @@ -87,4 +92,9 @@ public abstract class AbstractLocalDataAdapterWrapper implements LocalDataAdapte public boolean undoDataRemoval() { return mAdapter.undoDataRemoval(); } + + @Override + public void refresh(ContentResolver resolver, Uri uri) { + mAdapter.refresh(resolver, uri); + } } diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java index e384b1512..aaf5ebe59 100644 --- a/src/com/android/camera/data/CameraDataAdapter.java +++ b/src/com/android/camera/data/CameraDataAdapter.java @@ -16,11 +16,6 @@ package com.android.camera.data; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -34,11 +29,16 @@ import android.view.View; import com.android.camera.Storage; import com.android.camera.ui.FilmStripView.ImageData; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + /** * A {@link LocalDataAdapter} that provides data in the camera folder. */ public class CameraDataAdapter implements LocalDataAdapter { - private static final String TAG = CameraDataAdapter.class.getSimpleName(); + private static final String TAG = "CAM_CameraDataAdapter"; private static final int DEFAULT_DECODE_SIZE = 3000; private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "%" }; @@ -64,6 +64,15 @@ public class CameraDataAdapter implements LocalDataAdapter { } @Override + public LocalData getLocalData(int dataID) { + if (mImages == null || dataID < 0 || dataID >= mImages.size()) { + return null; + } + + return mImages.get(dataID); + } + + @Override public int getTotalNumber() { if (mImages == null) { return 0; @@ -73,7 +82,7 @@ public class CameraDataAdapter implements LocalDataAdapter { @Override public ImageData getImageData(int id) { - return getData(id); + return getLocalData(id); } @Override @@ -116,11 +125,6 @@ public class CameraDataAdapter implements LocalDataAdapter { } @Override - public void onDataCentered(int dataID, boolean centered) { - // do nothing. - } - - @Override public boolean canSwipeInFullScreen(int dataID) { if (dataID < mImages.size() && dataID > 0) { return mImages.get(dataID).canSwipeInFullScreen(); @@ -138,49 +142,60 @@ public class CameraDataAdapter implements LocalDataAdapter { mListener.onDataRemoved(dataID, d); } - private void insertData(LocalData data) { - if (mImages == null) { - mImages = new ArrayList<LocalData>(); - } - - // Since this function is mostly for adding the newest data, - // a simple linear search should yield the best performance over a - // binary search. - int pos = 0; - Comparator<LocalData> comp = new LocalData.NewestFirstComparator(); - for (; pos < mImages.size() - && comp.compare(data, mImages.get(pos)) > 0; pos++); - mImages.add(pos, data); - if (mListener != null) { - mListener.onDataInserted(pos, data); - } - } - + // TODO: put the database query on background thread @Override public void addNewVideo(ContentResolver cr, Uri uri) { Cursor c = cr.query(uri, LocalData.Video.QUERY_PROJECTION, MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH, LocalData.Video.QUERY_ORDER); - if (c != null && c.moveToFirst()) { - insertData(LocalData.Video.buildFromCursor(c)); + if (c == null || !c.moveToFirst()) { + return; + } + int pos = findDataByContentUri(uri); + LocalData.Video newData = LocalData.Video.buildFromCursor(c); + if (pos != -1) { + // A duplicate one, just do a substitute. + updateData(pos, newData); + } else { + // A new data. + insertData(newData); } } + // TODO: put the database query on background thread @Override public void addNewPhoto(ContentResolver cr, Uri uri) { Cursor c = cr.query(uri, LocalData.Photo.QUERY_PROJECTION, MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH, LocalData.Photo.QUERY_ORDER); - if (c != null && c.moveToFirst()) { - insertData(LocalData.Photo.buildFromCursor(c)); + if (c == null || !c.moveToFirst()) { + return; + } + int pos = findDataByContentUri(uri); + LocalData.Photo newData = LocalData.Photo.buildFromCursor(c); + if (pos != -1) { + // a duplicate one, just do a substitute. + Log.v(TAG, "found duplicate photo"); + updateData(pos, newData); + } else { + // a new data. + insertData(newData); } } @Override public int findDataByContentUri(Uri uri) { - // TODO: find the data. + for (int i = 0; i < mImages.size(); i++) { + Uri u = mImages.get(i).getContentUri(); + if (u == null) { + continue; + } + if (u.equals(uri)) { + return i; + } + } return -1; } @@ -208,51 +223,62 @@ public class CameraDataAdapter implements LocalDataAdapter { replaceData(null); } - private LocalData getData(int id) { - if (mImages == null || id >= mImages.size() || id < 0) { - return null; + @Override + public void refresh(ContentResolver resolver, Uri contentUri) { + int pos = findDataByContentUri(contentUri); + if (pos == -1) { + return; + } + + LocalData data = mImages.get(pos); + if (data.refresh(resolver)) { + updateData(pos, data); } - return mImages.get(id); } - // Update all the data but keep the camera data if already set. - private void replaceData(List<LocalData> list) { - boolean changed = (list != mImages); - LocalData cameraData = null; - if (mImages != null && mImages.size() > 0) { - cameraData = mImages.get(0); - if (cameraData.getType() != ImageData.TYPE_CAMERA_PREVIEW) { - cameraData = null; - } + @Override + public void updateData(final int pos, LocalData data) { + mImages.set(pos, data); + if (mListener != null) { + mListener.onDataUpdated(new UpdateReporter() { + @Override + public boolean isDataRemoved(int dataID) { + return false; + } + + @Override + public boolean isDataUpdated(int dataID) { + return (dataID == pos); + } + }); } + } - mImages = list; - if (cameraData != null) { - // camera view exists, so we make sure at least 1 data is in the list. - if (mImages == null) { - mImages = new ArrayList<LocalData>(); - } - mImages.add(0, cameraData); - if (mListener != null) { - // Only the camera data is not changed, everything else is changed. - mListener.onDataUpdated(new UpdateReporter() { - @Override - public boolean isDataRemoved(int id) { - return false; - } + @Override + public void insertData(LocalData data) { + if (mImages == null) { + mImages = new ArrayList<LocalData>(); + } - @Override - public boolean isDataUpdated(int id) { - if (id == 0) return false; - return true; - } - }); - } - } else { - // both might be null. - if (changed) { - mListener.onDataLoaded(); - } + // Since this function is mostly for adding the newest data, + // a simple linear search should yield the best performance over a + // binary search. + int pos = 0; + Comparator<LocalData> comp = new LocalData.NewestFirstComparator(); + for (; pos < mImages.size() + && comp.compare(data, mImages.get(pos)) > 0; pos++); + mImages.add(pos, data); + if (mListener != null) { + mListener.onDataInserted(pos, data); + } + } + + /** Update all the data */ + private void replaceData(List<LocalData> list) { + boolean changed = (list != mImages); + mImages = list; + if (changed) { + mListener.onDataLoaded(); } } diff --git a/src/com/android/camera/data/FixedFirstDataAdapter.java b/src/com/android/camera/data/FixedFirstDataAdapter.java index 34ba0a1a0..2bff22aa4 100644 --- a/src/com/android/camera/data/FixedFirstDataAdapter.java +++ b/src/com/android/camera/data/FixedFirstDataAdapter.java @@ -32,7 +32,7 @@ import com.android.camera.ui.FilmStripView.ImageData; public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper implements DataAdapter.Listener { - private final LocalData mFirstData; + private LocalData mFirstData; private Listener mListener; /** @@ -53,6 +53,14 @@ public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper } @Override + public LocalData getLocalData(int dataID) { + if (dataID == 0) { + return mFirstData; + } + return mAdapter.getLocalData(dataID - 1); + } + + @Override public void removeData(Context context, int dataID) { if (dataID > 0) { mAdapter.removeData(context, dataID - 1); @@ -69,6 +77,28 @@ public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper } @Override + public void updateData(int pos, LocalData data) { + if (pos == 0) { + mFirstData = data; + if (mListener != null) { + mListener.onDataUpdated(new UpdateReporter() { + @Override + public boolean isDataRemoved(int dataID) { + return false; + } + + @Override + public boolean isDataUpdated(int dataID) { + return (dataID == 0); + } + }); + } + } else { + mAdapter.updateData(pos - 1, data); + } + } + + @Override public int getTotalNumber() { return (mAdapter.getTotalNumber() + 1); } @@ -100,15 +130,6 @@ public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper } @Override - public void onDataCentered(int dataID, boolean centered) { - if (dataID != 0) { - mAdapter.onDataCentered(dataID, centered); - } else { - // TODO: notify the data - } - } - - @Override public void setListener(Listener listener) { mListener = listener; mAdapter.setListener((listener == null) ? null : this); @@ -132,12 +153,12 @@ public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper mListener.onDataUpdated(new UpdateReporter() { @Override public boolean isDataRemoved(int dataID) { - return reporter.isDataRemoved(dataID + 1); + return reporter.isDataRemoved(dataID - 1); } @Override public boolean isDataUpdated(int dataID) { - return reporter.isDataUpdated(dataID + 1); + return reporter.isDataUpdated(dataID - 1); } }); } diff --git a/src/com/android/camera/data/FixedLastDataAdapter.java b/src/com/android/camera/data/FixedLastDataAdapter.java index 16c047d1a..b8325ec72 100644 --- a/src/com/android/camera/data/FixedLastDataAdapter.java +++ b/src/com/android/camera/data/FixedLastDataAdapter.java @@ -29,7 +29,8 @@ import com.android.camera.ui.FilmStripView; */ public class FixedLastDataAdapter extends AbstractLocalDataAdapterWrapper { - private final LocalData mLastData; + private LocalData mLastData; + private Listener mListener; /** * Constructor. @@ -48,6 +49,25 @@ public class FixedLastDataAdapter extends AbstractLocalDataAdapterWrapper { } @Override + public void setListener(Listener listener) { + super.setListener(listener); + mListener = listener; + } + + @Override + public LocalData getLocalData(int dataID) { + int totalNumber = mAdapter.getTotalNumber(); + + if (dataID < totalNumber) { + return mAdapter.getLocalData(dataID); + } else if (dataID == totalNumber) { + return mLastData; + } + + return null; + } + + @Override public void removeData(Context context, int dataID) { if (dataID < mAdapter.getTotalNumber()) { mAdapter.removeData(context, dataID); @@ -60,6 +80,30 @@ public class FixedLastDataAdapter extends AbstractLocalDataAdapterWrapper { } @Override + public void updateData(final int pos, LocalData data) { + int totalNumber = mAdapter.getTotalNumber(); + + if (pos < totalNumber) { + mAdapter.updateData(pos, data); + } else if (pos == totalNumber) { + mLastData = data; + if (mListener != null) { + mListener.onDataUpdated(new UpdateReporter() { + @Override + public boolean isDataRemoved(int dataID) { + return false; + } + + @Override + public boolean isDataUpdated(int dataID) { + return (dataID == pos); + } + }); + } + } + } + + @Override public int getTotalNumber() { return mAdapter.getTotalNumber() + 1; } @@ -102,17 +146,6 @@ public class FixedLastDataAdapter extends AbstractLocalDataAdapterWrapper { } @Override - public void onDataCentered(int dataID, boolean centered) { - int totalNumber = mAdapter.getTotalNumber(); - - if (dataID < totalNumber) { - mAdapter.onDataCentered(dataID, centered); - } else if (dataID == totalNumber) { - // TODO: notify the data - } - } - - @Override public boolean canSwipeInFullScreen(int dataID) { int totalNumber = mAdapter.getTotalNumber(); diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java index eb2212c2a..10cf9aec6 100644 --- a/src/com/android/camera/data/LocalData.java +++ b/src/com/android/camera/data/LocalData.java @@ -32,7 +32,6 @@ import android.media.MediaMetadataRetriever; import android.net.Uri; import android.os.AsyncTask; import android.provider.MediaStore; -import android.provider.MediaStore.Images; import android.provider.MediaStore.Images.ImageColumns; import android.provider.MediaStore.Video.VideoColumns; import android.util.Log; @@ -62,15 +61,65 @@ public interface LocalData extends FilmStripView.ImageData { public static final int ACTION_DELETE = (1 << 1); View getView(Context c, int width, int height, Drawable placeHolder); + + /** + * Gets the date when this data is created. The returned date is also used + * for sorting data. + * + * @return The date when this data is created. + * @see {@link NewestFirstComparator} + */ long getDateTaken(); + + /** + * Gets the date when this data is modified. The returned date is also used + * for sorting data. + * + * @return The date when this data is modified. + * @see {@link NewestFirstComparator} + */ long getDateModified(); + + /** Gets the title of this data */ String getTitle(); - boolean isDataActionSupported(int action); + + /** + * Checks if the data actions (delete/play ...) can be applied on this data. + * + * @param actions The actions to check. + * @return Whether all the actions are supported. + */ + boolean isDataActionSupported(int actions); + boolean delete(Context c); + void onFullScreen(boolean fullScreen); + + /** Returns {@code true} if it allows swipe to filmstrip in full screen. */ boolean canSwipeInFullScreen(); + + /** + * Returns the path to the data on the storage. + * + * @return Empty path if there's none. + */ String getPath(); + /** + * Returns the content URI of this data item. + * + * @return {@code Uri.EMPTY} if not valid. + */ + Uri getContentUri(); + + /** + * Refresh the data content. + * + * @param resolver {@link ContentResolver} to refresh the data. + * @return {@code true} if success, {@code false} otherwise. + */ + boolean refresh(ContentResolver resolver); + static class NewestFirstComparator implements Comparator<LocalData> { /** Compare taken/modified date of LocalData in descent order to make @@ -103,7 +152,7 @@ public interface LocalData extends FilmStripView.ImageData { /** * A base class for all the local media files. The bitmap is loaded in * background thread. Subclasses should implement their own background - * loading thread by subclassing BitmapLoadTask and overriding + * loading thread by sub-classing BitmapLoadTask and overriding * doInBackground() to return a bitmap. */ abstract static class LocalMediaData implements LocalData { @@ -250,14 +299,6 @@ public interface LocalData extends FilmStripView.ImageData { } } - /** - * Returns the content URI of this data item. - */ - private Uri getContentUri() { - Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI; - return baseUri.buildUpon().appendPath(String.valueOf(id)).build(); - } - @Override public abstract int getType(); @@ -399,6 +440,32 @@ public interface LocalData extends FilmStripView.ImageData { } @Override + public Uri getContentUri() { + Uri baseUri = CONTENT_URI; + return baseUri.buildUpon().appendPath(String.valueOf(id)).build(); + } + + @Override + public boolean refresh(ContentResolver resolver) { + Cursor c = resolver.query( + getContentUri(), QUERY_PROJECTION, null, null, null); + if (c == null || !c.moveToFirst()) { + return false; + } + Photo newData = buildFromCursor(c); + id = newData.id; + title = newData.title; + mimeType = newData.mimeType; + dateTaken = newData.dateTaken; + dateModified = newData.dateModified; + path = newData.path; + orientation = newData.orientation; + width = newData.width; + height = newData.height; + return true; + } + + @Override protected BitmapLoadTask getBitmapLoadTask( ImageView v, int decodeWidth, int decodeHeight) { return new PhotoBitmapLoadTask(v, decodeWidth, decodeHeight); @@ -492,8 +559,7 @@ public interface LocalData extends FilmStripView.ImageData { d.path = c.getString(COL_DATA); d.width = c.getInt(COL_WIDTH); d.height = c.getInt(COL_HEIGHT); - d.mPlayUri = CONTENT_URI.buildUpon() - .appendPath(String.valueOf(d.id)).build(); + d.mPlayUri = d.getContentUri(); MediaMetadataRetriever retriever = new MediaMetadataRetriever(); retriever.setDataSource(d.path); String rotation = retriever.extractMetadata( @@ -543,6 +609,32 @@ public interface LocalData extends FilmStripView.ImageData { } @Override + public Uri getContentUri() { + Uri baseUri = CONTENT_URI; + return baseUri.buildUpon().appendPath(String.valueOf(id)).build(); + } + + @Override + public boolean refresh(ContentResolver resolver) { + Cursor c = resolver.query( + getContentUri(), QUERY_PROJECTION, null, null, null); + if (c == null && !c.moveToFirst()) { + return false; + } + Video newData = buildFromCursor(c); + id = newData.id; + title = newData.title; + mimeType = newData.mimeType; + dateTaken = newData.dateTaken; + dateModified = newData.dateModified; + path = newData.path; + width = newData.width; + height = newData.height; + mPlayUri = newData.mPlayUri; + return true; + } + + @Override public View getView(final Context ctx, int decodeWidth, int decodeHeight, Drawable placeHolder) { @@ -666,6 +758,16 @@ public interface LocalData extends FilmStripView.ImageData { } @Override + public Uri getContentUri() { + return Uri.EMPTY; + } + + @Override + public boolean refresh(ContentResolver resolver) { + return false; + } + + @Override public boolean isUIActionSupported(int action) { return false; } diff --git a/src/com/android/camera/data/LocalDataAdapter.java b/src/com/android/camera/data/LocalDataAdapter.java index 3b4f07dea..0a5fde0b5 100644 --- a/src/com/android/camera/data/LocalDataAdapter.java +++ b/src/com/android/camera/data/LocalDataAdapter.java @@ -36,6 +36,14 @@ public interface LocalDataAdapter extends DataAdapter { public void requestLoad(ContentResolver resolver); /** + * Returns the specified {@link LocalData}. + * + * @param dataID The ID of the {@link LocalData} to get. + * @return The {@link LocalData} to get. {@code null} if not available. + */ + public LocalData getLocalData(int dataID); + + /** * Remove the data in the local camera folder. * * @param context {@link Context} used to remove the data. @@ -60,6 +68,14 @@ public interface LocalDataAdapter extends DataAdapter { public void addNewPhoto(ContentResolver resolver, Uri uri); /** + * Refresh the data by {@link Uri}. + * + * @param resolver {@link ContentResolver} used to refresh the data. + * @param uri The {@link Uri} of the data to refresh. + */ + public void refresh(ContentResolver resolver, Uri uri); + + /** * Finds the {@link LocalData} of the specified content Uri. * * @param Uri The content Uri of the {@link LocalData}. @@ -88,4 +104,15 @@ public interface LocalDataAdapter extends DataAdapter { * @return {@code true} if there are items in the queue, {@code false} otherwise. */ public boolean undoDataRemoval(); + + /** + * Update the data in a specific position. + * + * @param pos The position of the data to be updated. + * @param data The new data. + */ + public void updateData(int pos, LocalData data); + + /** Insert a data. */ + public void insertData(LocalData data); } |