diff options
author | Angus Kong <shkong@google.com> | 2013-08-06 19:51:37 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-08-06 19:51:37 +0000 |
commit | 43d50328a2dcd3ab22821ce5d20715ad206dca1c (patch) | |
tree | 423f712a4195e26730fdedb7e4ce1207816c67cb /src/com/android/camera | |
parent | 1009bb05ec8f64d53e2faf0fc7c8096dbd018253 (diff) | |
parent | e256999a30f0bb2bf0eb6fbef4023c82d374a5d0 (diff) | |
download | android_packages_apps_Gallery2-43d50328a2dcd3ab22821ce5d20715ad206dca1c.tar.gz android_packages_apps_Gallery2-43d50328a2dcd3ab22821ce5d20715ad206dca1c.tar.bz2 android_packages_apps_Gallery2-43d50328a2dcd3ab22821ce5d20715ad206dca1c.zip |
Merge "Show PhotoSphere stitching progress." into gb-ub-photos-carlsbad
Diffstat (limited to 'src/com/android/camera')
-rw-r--r-- | src/com/android/camera/CameraActivity.java | 121 | ||||
-rw-r--r-- | src/com/android/camera/ImageTaskManager.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/data/AbstractLocalDataAdapterWrapper.java | 10 | ||||
-rw-r--r-- | src/com/android/camera/data/CameraDataAdapter.java | 165 | ||||
-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 | 133 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalDataAdapter.java | 27 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmStripView.java | 40 |
9 files changed, 449 insertions, 151 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index 7f71d5f31..7114f6191 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -32,6 +32,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.provider.Settings; +import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.OrientationEventListener; @@ -40,6 +41,7 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; +import android.widget.ProgressBar; import com.android.camera.data.CameraDataAdapter; import com.android.camera.data.CameraPreviewData; @@ -82,6 +84,8 @@ public class CameraActivity extends Activity private CameraModule mCurrentModule; private View mRootView; private FilmStripView mFilmStripView; + private ProgressBar mBottomProgress; + private View mPanoStitchingPanel; private int mResultCodeForTesting; private Intent mResultDataForTesting; private OnScreenHint mStorageHint; @@ -150,26 +154,65 @@ public class CameraActivity extends Activity sFirstStartAfterScreenOn = false; } - private FilmStripView.Listener mFilmStripListener = new FilmStripView.Listener() { - @Override - public void onDataPromoted(int dataID) { - removeData(dataID); - } + private FilmStripView.Listener mFilmStripListener = + new FilmStripView.Listener() { + @Override + public void onDataPromoted(int dataID) { + removeData(dataID); + } - @Override - public void onDataDemoted(int dataID) { - removeData(dataID); - } + @Override + public void onDataDemoted(int dataID) { + removeData(dataID); + } - @Override - public void onDataFullScreenChange(int dataID, boolean full) { - } + @Override + public void onDataFullScreenChange(int dataID, boolean full) { + } - @Override - public void onSwitchMode(boolean toCamera) { - mCurrentModule.onSwitchMode(toCamera); - } - }; + @Override + public void onSwitchMode(boolean toCamera) { + mCurrentModule.onSwitchMode(toCamera); + } + + @Override + public void onCurrentDataChanged(int dataID, boolean current) { + if (!current) { + hidePanoStitchingProgress(); + } else { + LocalData currentData = mDataAdapter.getLocalData(dataID); + if (currentData == null) { + Log.w(TAG, "Current data ID not found."); + hidePanoStitchingProgress(); + return; + } + Uri contentUri = currentData.getContentUri(); + if (contentUri == null) { + hidePanoStitchingProgress(); + return; + } + int panoStitchingProgress = mPanoramaManager.getTaskProgress(contentUri); + if (panoStitchingProgress < 0) { + hidePanoStitchingProgress(); + return; + } + showPanoStitchingProgress(); + updateStitchingProgress(panoStitchingProgress); + } + } + }; + + private void hidePanoStitchingProgress() { + mPanoStitchingPanel.setVisibility(View.GONE); + } + + private void showPanoStitchingProgress() { + mPanoStitchingPanel.setVisibility(View.VISIBLE); + } + + private void updateStitchingProgress(int progress) { + mBottomProgress.setProgress(progress); + } private Runnable mDeletionRunnable = new Runnable() { @Override @@ -181,16 +224,50 @@ public class CameraActivity extends Activity private ImageTaskManager.TaskListener mStitchingListener = new ImageTaskManager.TaskListener() { @Override - public void onTaskQueued(String filePath, Uri imageUri) { + public void onTaskQueued(String filePath, final Uri imageUri) { + mMainHandler.post(new Runnable() { + @Override + public void run() { + notifyNewMedia(imageUri); + } + }); } @Override - public void onTaskDone(String filePath, Uri imageUri) { + public void onTaskDone(String filePath, final Uri imageUri) { + Log.v(TAG, "onTaskDone:" + filePath); + mMainHandler.post(new Runnable() { + @Override + public void run() { + int doneID = mDataAdapter.findDataByContentUri(imageUri); + int currentDataId = mFilmStripView.getCurrentId(); + + if (currentDataId == doneID) { + hidePanoStitchingProgress(); + updateStitchingProgress(0); + } + + mDataAdapter.refresh(getContentResolver(), imageUri); + } + }); } @Override public void onTaskProgress( - String filePath, Uri imageUri, int progress) { + String filePath, final Uri imageUri, final int progress) { + mMainHandler.post(new Runnable() { + @Override + public void run() { + int currentDataId = mFilmStripView.getCurrentId(); + if (currentDataId == -1) { + return; + } + if (imageUri.equals( + mDataAdapter.getLocalData(currentDataId).getContentUri())) { + updateStitchingProgress(progress); + } + } + }); } }; @@ -207,6 +284,8 @@ public class CameraActivity extends Activity } else if (mimeType.startsWith("image/")) { Util.broadcastNewPicture(this, uri); mDataAdapter.addNewPhoto(cr, uri); + } else if (mimeType.startsWith("application/stitching-preview")) { + mDataAdapter.addNewPhoto(cr, uri); } else { android.util.Log.w(TAG, "Unknown new media with MIME type:" + mimeType + ", uri:" + uri); @@ -276,6 +355,8 @@ public class CameraActivity extends Activity LayoutInflater inflater = getLayoutInflater(); View rootLayout = inflater.inflate(R.layout.camera, null, false); mRootView = rootLayout.findViewById(R.id.camera_app_root); + mPanoStitchingPanel = (View) findViewById(R.id.pano_stitching_progress_panel); + mBottomProgress = (ProgressBar) findViewById(R.id.pano_stitching_progress_bar); mCameraPreviewData = new CameraPreviewData(rootLayout, FilmStripView.ImageData.SIZE_FULL, FilmStripView.ImageData.SIZE_FULL); diff --git a/src/com/android/camera/ImageTaskManager.java b/src/com/android/camera/ImageTaskManager.java index 1324942fd..601de4c50 100644 --- a/src/com/android/camera/ImageTaskManager.java +++ b/src/com/android/camera/ImageTaskManager.java @@ -21,7 +21,7 @@ import android.net.Uri; /** * The interface for background image processing task manager. */ -interface ImageTaskManager { +public interface ImageTaskManager { /** * Callback interface for task events. 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 3605f7190..aaf5ebe59 100644 --- a/src/com/android/camera/data/CameraDataAdapter.java +++ b/src/com/android/camera/data/CameraDataAdapter.java @@ -28,7 +28,6 @@ import android.view.View; import com.android.camera.Storage; import com.android.camera.ui.FilmStripView.ImageData; -import com.android.gallery3d.util.LightCycleHelper.PanoramaViewHelper; import java.util.ArrayList; import java.util.Collections; @@ -39,7 +38,7 @@ 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 + "%" }; @@ -65,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; @@ -74,7 +82,7 @@ public class CameraDataAdapter implements LocalDataAdapter { @Override public ImageData getImageData(int id) { - return getData(id); + return getLocalData(id); } @Override @@ -117,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(); @@ -139,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; } @@ -209,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 efccfe332..852066bd3 100644 --- a/src/com/android/camera/data/LocalData.java +++ b/src/com/android/camera/data/LocalData.java @@ -62,15 +62,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 @@ -101,16 +151,10 @@ public interface LocalData extends FilmStripView.ImageData { // Implementations below. /** -<<<<<<< HEAD * 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. -======= - * 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 - * sub-classing BitmapLoadTask and overriding doInBackground() to return a bitmap. ->>>>>>> Add LocalDataAdapter and wrappers. */ abstract static class LocalMediaData implements LocalData { protected long id; @@ -256,14 +300,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(); @@ -405,6 +441,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); @@ -498,8 +560,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( @@ -549,6 +610,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) { @@ -672,6 +759,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); } diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index 8a1a85a55..f7f388341 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -38,7 +38,7 @@ import com.android.gallery3d.util.LightCycleHelper.PanoramaViewHelper; public class FilmStripView extends ViewGroup { @SuppressWarnings("unused") - private static final String TAG = "FilmStripView"; + private static final String TAG = "CAM_FilmStripView"; private static final int BUFFER_SIZE = 5; private static final int DURATION_GEOMETRY_ADJUST = 200; @@ -102,7 +102,6 @@ public class FilmStripView extends ViewGroup { public static final int TYPE_NONE = 0; public static final int TYPE_CAMERA_PREVIEW = 1; public static final int TYPE_PHOTO = 2; - public static final int TYPE_VIDEO = 3; // Actions allowed to be performed on the image data. // The actions are defined bit-wise so we can use bit operations like @@ -197,7 +196,7 @@ public class FilmStripView extends ViewGroup { } /** - * An interface which defines the listener for UI actions over + * An interface which defines the listener for data events over * {@link ImageData}. */ public interface Listener { @@ -246,7 +245,7 @@ public class FilmStripView extends ViewGroup { public void suggestViewSizeBound(int w, int h); /** - * Sets the listener for FilmStripView UI actions over the ImageData. + * Sets the listener for data events over the ImageData. * * @param listener The listener to use. */ @@ -263,16 +262,6 @@ public class FilmStripView extends ViewGroup { public void onDataFullScreen(int dataID, boolean fullScreen); /** - * The callback when the item is centered/off-centered. - * TODO: Calls this function actually. - * - * @param dataID The ID of the image data. - * @param centered {@code true} if the data is centered. - * {@code false} otherwise. - */ - public void onDataCentered(int dataID, boolean centered); - - /** * Returns {@code true} if the view of the data can be moved by swipe * gesture when in full-screen. * @@ -310,6 +299,15 @@ public class FilmStripView extends ViewGroup { * {@code false} */ public void onSwitchMode(boolean toCamera); + + /** + * The callback when the item is centered/off-centered. + * + * @param dataID The ID of the image data. + * @param current {@code true} if the data is the current one. + * {@code false} otherwise. + */ + public void onCurrentDataChanged(int dataID, boolean current); } /** @@ -500,7 +498,7 @@ public class FilmStripView extends ViewGroup { return false; } - public int getCurrentType() { + private int getCurrentType() { if (mDataAdapter == null) { return ImageData.TYPE_NONE; } @@ -653,8 +651,7 @@ public class FilmStripView extends ViewGroup { private void stepIfNeeded() { if (!inFilmStrip() && !inFullScreen()) { // The good timing to step to the next view is when everything is - // not in - // transition. + // not in transition. return; } int nearest = findTheNearestView(mCenterX); @@ -662,6 +659,10 @@ public class FilmStripView extends ViewGroup { if (nearest == -1 || nearest == mCurrentInfo) return; + // Going to change the current info, notify the listener. + if (mListener != null) { + mListener.onCurrentDataChanged(mViewInfo[mCurrentInfo].getID(), false); + } int adjust = nearest - mCurrentInfo; if (adjust > 0) { for (int k = 0; k < adjust; k++) { @@ -690,6 +691,9 @@ public class FilmStripView extends ViewGroup { } } } + if (mListener != null) { + mListener.onCurrentDataChanged(mViewInfo[mCurrentInfo].getID(), true); + } } /** Don't go beyond the bound. */ @@ -741,7 +745,7 @@ public class FilmStripView extends ViewGroup { /** * @return The ID of the current item, or -1. */ - private int getCurrentId() { + public int getCurrentId() { ViewInfo current = mViewInfo[mCurrentInfo]; if (current == null) { return -1; |