diff options
-rw-r--r-- | src/com/android/camera/NewCameraActivity.java | 66 | ||||
-rw-r--r-- | src/com/android/camera/NewPhotoModule.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/NewPhotoUI.java | 6 | ||||
-rw-r--r-- | src/com/android/camera/NewVideoMenu.java | 4 | ||||
-rw-r--r-- | src/com/android/camera/NewVideoModule.java | 190 | ||||
-rw-r--r-- | src/com/android/camera/NewVideoUI.java | 53 | ||||
-rw-r--r-- | src/com/android/camera/data/CameraDataAdapter.java | 88 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalData.java | 74 |
8 files changed, 262 insertions, 221 deletions
diff --git a/src/com/android/camera/NewCameraActivity.java b/src/com/android/camera/NewCameraActivity.java index 3aee15053..3313edea3 100644 --- a/src/com/android/camera/NewCameraActivity.java +++ b/src/com/android/camera/NewCameraActivity.java @@ -37,8 +37,10 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; +import android.widget.ImageView; import com.android.camera.data.CameraDataAdapter; +import com.android.camera.data.LocalData; import com.android.camera.ui.CameraSwitcher.CameraSwitchListener; import com.android.camera.ui.FilmStripView; import com.android.camera.ui.NewCameraRootView; @@ -132,8 +134,12 @@ public class NewCameraActivity extends Activity } private void unbindMediaSaveService() { - mMediaSaveService.setListener(null); - unbindService(mConnection); + if (mMediaSaveService != null) { + mMediaSaveService.setListener(null); + } + if (mConnection != null) { + unbindService(mConnection); + } } @Override @@ -148,8 +154,6 @@ public class NewCameraActivity extends Activity String action = intent.getAction(); if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action)) { mSecureCamera = true; - // Use a new album when this is started from the lock screen. - //TODO: sSecureAlbumId++; } else if (ACTION_IMAGE_CAPTURE_SECURE.equals(action)) { mSecureCamera = true; } else { @@ -232,7 +236,20 @@ public class NewCameraActivity extends Activity mCurrentModule.onResumeAfterSuper(); // The loading is done in background and will update the filmstrip later. - mDataAdapter.requestLoad(getContentResolver()); + if (!mSecureCamera) { + mDataAdapter.requestLoad(getContentResolver()); + } else { + // Flush out all the original data first. + mDataAdapter.flush(); + ImageView v = (ImageView) getLayoutInflater().inflate( + R.layout.secure_album_placeholder, null); + mDataAdapter.addLocalData( + new LocalData.LocalViewData( + v, + v.getDrawable().getIntrinsicWidth(), + v.getDrawable().getIntrinsicHeight(), + 0, 0)); + } } @Override @@ -249,9 +266,6 @@ public class NewCameraActivity extends Activity @Override public boolean dispatchTouchEvent(MotionEvent m) { - //if (mFilmStripView.isInCameraFullscreen()) { - // return mCurrentModule.dispatchTouchEvent(m); - //} return mFilmStripView.dispatchTouchEvent(m); } public boolean isAutoRotateScreen() { @@ -371,4 +385,40 @@ public class NewCameraActivity extends Activity @Override public void onShowSwitcherPopup() { } + + // Accessor methods for getting latency times used in performance testing + public long getAutoFocusTime() { + return (mCurrentModule instanceof PhotoModule) ? + ((PhotoModule) mCurrentModule).mAutoFocusTime : -1; + } + + public long getShutterLag() { + return (mCurrentModule instanceof PhotoModule) ? + ((PhotoModule) mCurrentModule).mShutterLag : -1; + } + + public long getShutterToPictureDisplayedTime() { + return (mCurrentModule instanceof PhotoModule) ? + ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1; + } + + public long getPictureDisplayedToJpegCallbackTime() { + return (mCurrentModule instanceof PhotoModule) ? + ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1; + } + + public long getJpegCallbackFinishTime() { + return (mCurrentModule instanceof PhotoModule) ? + ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1; + } + + public long getCaptureStartTime() { + return (mCurrentModule instanceof PhotoModule) ? + ((PhotoModule) mCurrentModule).mCaptureStartTime : -1; + } + + public boolean isRecording() { + return (mCurrentModule instanceof VideoModule) ? + ((VideoModule) mCurrentModule).isRecording() : false; + } } diff --git a/src/com/android/camera/NewPhotoModule.java b/src/com/android/camera/NewPhotoModule.java index ecbbbf36d..e5d50f383 100644 --- a/src/com/android/camera/NewPhotoModule.java +++ b/src/com/android/camera/NewPhotoModule.java @@ -263,8 +263,6 @@ public class NewPhotoModule @Override public void onMediaSaved(Uri uri) { if (uri != null) { - // TODO: Commenting out the line below for now. need to get it working - // mActivity.addSecureAlbumItemIfNeeded(false, uri); mActivity.notifyNewMedia(uri); } } diff --git a/src/com/android/camera/NewPhotoUI.java b/src/com/android/camera/NewPhotoUI.java index d6e50574e..cd93a7ea9 100644 --- a/src/com/android/camera/NewPhotoUI.java +++ b/src/com/android/camera/NewPhotoUI.java @@ -274,6 +274,7 @@ public class NewPhotoUI implements PieListener, if (mPieRenderer == null) { mPieRenderer = new PieRenderer(mActivity); mPieRenderer.setPieListener(this); + mRenderOverlay.addRenderer(mPieRenderer); } if (mMenu == null) { @@ -284,9 +285,8 @@ public class NewPhotoUI implements PieListener, if (mZoomRenderer == null) { mZoomRenderer = new ZoomRenderer(mActivity); + mRenderOverlay.addRenderer(mZoomRenderer); } - mRenderOverlay.addRenderer(mPieRenderer); - mRenderOverlay.addRenderer(mZoomRenderer); if (mGestures == null) { // this will handle gesture disambiguation and dispatching @@ -647,7 +647,7 @@ public class NewPhotoUI implements PieListener, public void onPieOpened(int centerX, int centerY) { //TODO: mActivity.cancelActivityTouchHandling(); //TODO: mActivity.setSwipingEnabled(false); - dismissPopup(false); + dismissPopup(); if (mFaceView != null) { mFaceView.setBlockDraw(true); } diff --git a/src/com/android/camera/NewVideoMenu.java b/src/com/android/camera/NewVideoMenu.java index 1038628b5..70f73ec39 100644 --- a/src/com/android/camera/NewVideoMenu.java +++ b/src/com/android/camera/NewVideoMenu.java @@ -35,10 +35,6 @@ public class NewVideoMenu extends PieController TimeIntervalPopup.Listener { private static String TAG = "CAM_VideoMenu"; - private static final int POS_WB = 1; - private static final int POS_SET = 2; - private static final int POS_FLASH = 3; - private static final int POS_SWITCH = 4; private NewVideoUI mUI; private String[] mOtherKeys; diff --git a/src/com/android/camera/NewVideoModule.java b/src/com/android/camera/NewVideoModule.java index 96f0312a4..d613eb4e5 100644 --- a/src/com/android/camera/NewVideoModule.java +++ b/src/com/android/camera/NewVideoModule.java @@ -45,6 +45,7 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.SystemClock; import android.provider.MediaStore; +import android.provider.MediaStore.MediaColumns; import android.provider.MediaStore.Video; import android.util.Log; import android.view.KeyEvent; @@ -93,6 +94,7 @@ public class NewVideoModule implements NewCameraModule, private static final int SWITCH_CAMERA = 8; private static final int SWITCH_CAMERA_START_ANIMATION = 9; private static final int HIDE_SURFACE_VIEW = 10; + private static final int CAPTURE_ANIMATION_DONE = 11; private static final int SCREEN_DELAY = 2 * 60 * 1000; @@ -176,7 +178,6 @@ public class NewVideoModule implements NewCameraModule, private LocationManager mLocationManager; private OrientationManager mOrientationManager; - private VideoNamer mVideoNamer; private Surface mSurface; private int mPendingSwitchCameraId; private boolean mOpenCameraFail; @@ -193,12 +194,24 @@ public class NewVideoModule implements NewCameraModule, private boolean mRestoreFlash; // This is used to check if we need to restore the flash // status when going back from gallery. - private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener = + private final MediaSaveService.OnMediaSavedListener mOnVideoSavedListener = new MediaSaveService.OnMediaSavedListener() { @Override public void onMediaSaved(Uri uri) { if (uri != null) { - mActivity.notifyNewMedia(uri); + mActivity.sendBroadcast( + new Intent(Util.ACTION_NEW_VIDEO, uri)); + Util.broadcastNewPicture(mActivity, uri); + } + } + }; + + private final MediaSaveService.OnMediaSavedListener mOnPhotoSavedListener = + new MediaSaveService.OnMediaSavedListener() { + @Override + public void onMediaSaved(Uri uri) { + if (uri != null) { + Util.broadcastNewPicture(mActivity, uri); } } }; @@ -284,6 +297,11 @@ public class NewVideoModule implements NewCameraModule, break; } + case CAPTURE_ANIMATION_DONE: { + mUI.enablePreviewThumb(false); + break; + } + default: Log.v(TAG, "Unhandled message: " + msg.what); break; @@ -395,7 +413,7 @@ public class NewVideoModule implements NewCameraModule, initializeVideoControl(); mPendingSwitchCameraId = -1; - mUI.updateOnScreenIndicators(mParameters); + mUI.updateOnScreenIndicators(mParameters, mPreferences); // Disable the shutter button if effects are ON since it might take // a little more time for the effects preview to be ready. We do not @@ -556,6 +574,14 @@ public class NewVideoModule implements NewCameraModule, // will not be continuous for a short period of time. // TODO: need to get the capture animation to work // ((CameraScreenNail) mActivity.mCameraScreenNail).animateCapture(mDisplayRotation); + + mUI.enablePreviewThumb(true); + + // Make sure to disable the thumbnail preview after the + // animation is done to disable the click target. + mHandler.removeMessages(CAPTURE_ANIMATION_DONE); + mHandler.sendEmptyMessageDelayed(CAPTURE_ANIMATION_DONE, + CaptureAnimManager.getAnimationDuration()); } } } @@ -760,7 +786,6 @@ public class NewVideoModule implements NewCameraModule, // Dismiss open menu if exists. PopupManager.getInstance(mActivity).notifyShowPopup(null); - mVideoNamer = new VideoNamer(); UsageStatistics.onContentViewChanged( UsageStatistics.COMPONENT_CAMERA, "VideoModule"); } @@ -936,7 +961,6 @@ public class NewVideoModule implements NewCameraModule, // that will close down the effects are well, thus making this if // condition invalid. closeVideoFileDescriptor(); - clearVideoNamer(); } releasePreviewResources(); @@ -1317,10 +1341,11 @@ public class NewVideoModule implements NewCameraModule, String mime = convertOutputFormatToMimeType(outputFileFormat); String path = Storage.DIRECTORY + '/' + filename; String tmpPath = path + ".tmp"; - mCurrentVideoValues = new ContentValues(7); + mCurrentVideoValues = new ContentValues(9); mCurrentVideoValues.put(Video.Media.TITLE, title); mCurrentVideoValues.put(Video.Media.DISPLAY_NAME, filename); mCurrentVideoValues.put(Video.Media.DATE_TAKEN, dateTaken); + mCurrentVideoValues.put(MediaColumns.DATE_MODIFIED, dateTaken / 1000); mCurrentVideoValues.put(Video.Media.MIME_TYPE, mime); mCurrentVideoValues.put(Video.Media.DATA, path); mCurrentVideoValues.put(Video.Media.RESOLUTION, @@ -1331,68 +1356,25 @@ public class NewVideoModule implements NewCameraModule, mCurrentVideoValues.put(Video.Media.LATITUDE, loc.getLatitude()); mCurrentVideoValues.put(Video.Media.LONGITUDE, loc.getLongitude()); } - mVideoNamer.prepareUri(mContentResolver, mCurrentVideoValues); mVideoFilename = tmpPath; Log.v(TAG, "New video filename: " + mVideoFilename); } - private boolean addVideoToMediaStore() { - boolean fail = false; + private void saveVideo() { if (mVideoFileDescriptor == null) { - mCurrentVideoValues.put(Video.Media.SIZE, - new File(mCurrentVideoFilename).length()); long duration = SystemClock.uptimeMillis() - mRecordingStartTime; if (duration > 0) { if (mCaptureTimeLapse) { duration = getTimeLapseVideoLength(duration); } - mCurrentVideoValues.put(Video.Media.DURATION, duration); } else { Log.w(TAG, "Video duration <= 0 : " + duration); } - try { - mCurrentVideoUri = mVideoNamer.getUri(); - //TODO: mActivity.addSecureAlbumItemIfNeeded(true, mCurrentVideoUri); - - // Rename the video file to the final name. This avoids other - // apps reading incomplete data. We need to do it after the - // above mVideoNamer.getUri() call, so we are certain that the - // previous insert to MediaProvider is completed. - String finalName = mCurrentVideoValues.getAsString( - Video.Media.DATA); - if (new File(mCurrentVideoFilename).renameTo(new File(finalName))) { - mCurrentVideoFilename = finalName; - } - - mContentResolver.update(mCurrentVideoUri, mCurrentVideoValues - , null, null); - mActivity.notifyNewMedia(mCurrentVideoUri); - } catch (Exception e) { - // We failed to insert into the database. This can happen if - // the SD card is unmounted. - Log.e(TAG, "failed to add video to media store", e); - mCurrentVideoUri = null; - mCurrentVideoFilename = null; - fail = true; - } finally { - Log.v(TAG, "Current video URI: " + mCurrentVideoUri); - } + mActivity.getMediaSaveService().addVideo(mCurrentVideoFilename, + duration, mCurrentVideoValues, + mOnVideoSavedListener, mContentResolver); } mCurrentVideoValues = null; - return fail; - } - - private void deleteCurrentVideo() { - // Remove the video and the uri if the uri is not passed in by intent. - if (mCurrentVideoFilename != null) { - deleteVideoFile(mCurrentVideoFilename); - mCurrentVideoFilename = null; - if (mCurrentVideoUri != null) { - mContentResolver.delete(mCurrentVideoUri, null, null); - mCurrentVideoUri = null; - } - } - mActivity.updateStorageSpaceAndHint(); } private void deleteVideoFile(String fileName) { @@ -1463,6 +1445,7 @@ public class NewVideoModule implements NewCameraModule, private void startVideoRecording() { Log.v(TAG, "startVideoRecording"); + mUI.enablePreviewThumb(false); // TODO: mActivity.setSwipingEnabled(false); mActivity.updateStorageSpaceAndHint(); @@ -1471,6 +1454,7 @@ public class NewVideoModule implements NewCameraModule, return; } + if (!mCameraDevice.waitDone()) return; mCurrentVideoUri = null; if (effectsActive()) { initializeEffectsRecording(); @@ -1581,7 +1565,7 @@ public class NewVideoModule implements NewCameraModule, try { if (effectsActive()) { // This is asynchronous, so we can't add to media store now because thumbnail - // may not be ready. In such case addVideoToMediaStore is called later + // may not be ready. In such case saveVideo() is called later // through a callback from the MediaEncoderFilter to EffectsRecorder, // and then to the VideoModule. mEffectsRecorder.stopRecording(); @@ -1629,7 +1613,7 @@ public class NewVideoModule implements NewCameraModule, mUI.setOrientationIndicator(0, true); keepScreenOnAwhile(); if (shouldAddToMediaStoreNow) { - if (addVideoToMediaStore()) fail = true; + saveVideo(); } } // always release media recorder if no effects running @@ -1888,7 +1872,8 @@ public class NewVideoModule implements NewCameraModule, checkQualityAndStartPreview(); } else if (effectMsg == EffectsRecorder.EFFECT_MSG_RECORDING_DONE) { // This follows the codepath from onStopVideoRecording. - if (mEffectsDisplayResult && !addVideoToMediaStore()) { + if (mEffectsDisplayResult) { + saveVideo(); if (mIsVideoCaptureIntent) { if (mQuickCapture) { doReturnToCaller(true); @@ -1902,7 +1887,6 @@ public class NewVideoModule implements NewCameraModule, // had to wait till the effects recording is complete to do this. if (mPaused) { closeVideoFileDescriptor(); - clearVideoNamer(); } } else if (effectMsg == EffectsRecorder.EFFECT_MSG_PREVIEW_RUNNING) { // Enable the shutter button once the preview is complete. @@ -1994,7 +1978,7 @@ public class NewVideoModule implements NewCameraModule, } else { setCameraParameters(); } - mUI.updateOnScreenIndicators(mParameters); + mUI.updateOnScreenIndicators(mParameters, mPreferences); } } @@ -2030,7 +2014,7 @@ public class NewVideoModule implements NewCameraModule, // Start switch camera animation. Post a message because // onFrameAvailable from the old camera may already exist. mHandler.sendEmptyMessage(SWITCH_CAMERA_START_ANIMATION); - mUI.updateOnScreenIndicators(mParameters); + mUI.updateOnScreenIndicators(mParameters, mPreferences); } // Preview texture has been copied. Now camera can be released and the @@ -2169,7 +2153,7 @@ public class NewVideoModule implements NewCameraModule, Size s = mParameters.getPictureSize(); mActivity.getMediaSaveService().addImage( data, title, dateTaken, loc, s.width, s.height, orientation, - exif, mOnMediaSavedListener, mContentResolver); + exif, mOnPhotoSavedListener, mContentResolver); } private boolean resetEffect() { @@ -2219,90 +2203,6 @@ public class NewVideoModule implements NewCameraModule, editor.apply(); } - private void clearVideoNamer() { - if (mVideoNamer != null) { - mVideoNamer.finish(); - mVideoNamer = null; - } - } - - private static class VideoNamer extends Thread { - private boolean mRequestPending; - private ContentResolver mResolver; - private ContentValues mValues; - private boolean mStop; - private Uri mUri; - - // Runs in main thread - public VideoNamer() { - start(); - } - - // Runs in main thread - public synchronized void prepareUri( - ContentResolver resolver, ContentValues values) { - mRequestPending = true; - mResolver = resolver; - mValues = new ContentValues(values); - notifyAll(); - } - - // Runs in main thread - public synchronized Uri getUri() { - // wait until the request is done. - while (mRequestPending) { - try { - wait(); - } catch (InterruptedException ex) { - // ignore. - } - } - Uri uri = mUri; - mUri = null; - return uri; - } - - // Runs in namer thread - @Override - public synchronized void run() { - while (true) { - if (mStop) break; - if (!mRequestPending) { - try { - wait(); - } catch (InterruptedException ex) { - // ignore. - } - continue; - } - cleanOldUri(); - generateUri(); - mRequestPending = false; - notifyAll(); - } - cleanOldUri(); - } - - // Runs in main thread - public synchronized void finish() { - mStop = true; - notifyAll(); - } - - // Runs in namer thread - private void generateUri() { - Uri videoTable = Uri.parse("content://media/external/video/media"); - mUri = mResolver.insert(videoTable, mValues); - } - - // Runs in namer thread - private void cleanOldUri() { - if (mUri == null) return; - mResolver.delete(mUri, null, null); - mUri = null; - } - } - @Override public boolean updateStorageHintOnResume() { return true; diff --git a/src/com/android/camera/NewVideoUI.java b/src/com/android/camera/NewVideoUI.java index ffc1c35f4..915269032 100644 --- a/src/com/android/camera/NewVideoUI.java +++ b/src/com/android/camera/NewVideoUI.java @@ -82,14 +82,14 @@ public class NewVideoUI implements PieRenderer.PieListener, private NewPreviewGestures mGestures; private View mMenuButton; private View mBlocker; - private View mOnScreenIndicators; - private ImageView mFlashIndicator; + private OnScreenIndicators mOnScreenIndicators; private RotateLayout mRecordingTimeRect; private final Object mLock = new Object(); private SurfaceTexture mSurfaceTexture; private VideoController mController; private int mZoomMax; private List<Integer> mZoomRatios; + private View mPreviewThumb; private SurfaceView mSurfaceView = null; private int mPreviewWidth = 0; @@ -168,8 +168,9 @@ public class NewVideoUI implements PieRenderer.PieListener, }); mCameraControls = mActivity.findViewById(R.id.camera_controls); - mOnScreenIndicators = mActivity.findViewById(R.id.on_screen_indicators); - mFlashIndicator = (ImageView) mActivity.findViewById(R.id.menu_flash_indicator); + mOnScreenIndicators = new OnScreenIndicators(mActivity, + mActivity.findViewById(R.id.on_screen_indicators)); + mOnScreenIndicators.resetToDefault(); if (mController.isVideoCaptureIntent()) { hideSwitcher(); mActivity.getLayoutInflater().inflate(R.layout.review_module_control, (ViewGroup) mCameraControls); @@ -362,6 +363,14 @@ public class NewVideoUI implements PieRenderer.PieListener, mRenderOverlay.setGestures(mGestures); } mGestures.setRenderOverlay(mRenderOverlay); + + mPreviewThumb = mActivity.findViewById(R.id.preview_thumb); + mPreviewThumb.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + // TODO: Go to filmstrip view + } + }); } public void setPrefChangedListener(OnPreferenceChangedListener listener) { @@ -383,22 +392,12 @@ public class NewVideoUI implements PieRenderer.PieListener, mLabelsLinearLayout = (LinearLayout) mRootView.findViewById(R.id.labels); } - public void updateOnScreenIndicators(Parameters param) { - if (param == null) return; - String value = param.getFlashMode(); - if (mFlashIndicator == null) return; - if (value == null || Parameters.FLASH_MODE_OFF.equals(value)) { - mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_off); - } else { - if (Parameters.FLASH_MODE_AUTO.equals(value)) { - mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_auto); - } else if (Parameters.FLASH_MODE_ON.equals(value) - || Parameters.FLASH_MODE_TORCH.equals(value)) { - mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_on); - } else { - mFlashIndicator.setImageResource(R.drawable.ic_indicator_flash_off); - } - } + public void updateOnScreenIndicators(Parameters param, ComboPreferences prefs) { + mOnScreenIndicators.updateFlashOnScreenIndicator(param.getFlashMode()); + boolean location = RecordLocationPreference.get( + prefs, mActivity.getContentResolver()); + mOnScreenIndicators.updateLocationIndicator(location); + } public void setAspectRatio(double ratio) { @@ -434,6 +433,9 @@ public class NewVideoUI implements PieRenderer.PieListener, } public void dismissPopup(boolean topLevelPopupOnly, boolean fullScreen) { + // In review mode, we do not want to bring up the camera UI + if (mController.isInReviewMode()) return; + if (fullScreen) { showUI(); mBlocker.setVisibility(View.VISIBLE); @@ -611,6 +613,17 @@ public class NewVideoUI implements PieRenderer.PieListener, return mTextureView.getVisibility() == View.VISIBLE; } + /** + * Enable or disable the preview thumbnail for click events. + */ + public void enablePreviewThumb(boolean enabled) { + if (enabled) { + mPreviewThumb.setVisibility(View.VISIBLE); + } else { + mPreviewThumb.setVisibility(View.GONE); + } + } + private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener { @Override public void onZoomValueChanged(int index) { diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java index 6e2ff101b..32b3afecc 100644 --- a/src/com/android/camera/data/CameraDataAdapter.java +++ b/src/com/android/camera/data/CameraDataAdapter.java @@ -164,6 +164,55 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { } } + // 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; + } + } + + 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 boolean isDataUpdated(int id) { + if (id == 0) return false; + return true; + } + }); + } + } else { + // both might be null. + if (changed) { + mListener.onDataLoaded(); + } + } + } + + public void flush() { + replaceData(null); + } + + public void addLocalData(LocalData data) { + insertData(data); + } + private LocalData buildCameraImageData(int width, int height) { LocalData d = new CameraPreviewData(width, height); return d; @@ -277,43 +326,7 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { @Override protected void onPostExecute(List<LocalData> l) { - boolean changed = (l != mImages); - LocalData cameraData = null; - if (mImages != null && mImages.size() > 0) { - cameraData = mImages.get(0); - if (cameraData.getType() != ImageData.TYPE_CAMERA_PREVIEW) { - cameraData = null; - } - } - - mImages = l; - 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 boolean isDataUpdated(int id) { - if (id == 0) return false; - return true; - } - }); - } - } else { - // both might be null. - if (changed) { - mListener.onDataLoaded(); - } - } + replaceData(l); } } @@ -378,5 +391,4 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { // do nothing. } } - } diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java index 5acdee162..9ebc9caa3 100644 --- a/src/com/android/camera/data/LocalData.java +++ b/src/com/android/camera/data/LocalData.java @@ -41,7 +41,7 @@ import java.util.Date; /* An abstract interface that represents the local media data. Also implements * Comparable interface so we can sort in DataAdapter. */ -abstract interface LocalData extends FilmStripView.ImageData { +public abstract interface LocalData extends FilmStripView.ImageData { static final String TAG = "LocalData"; abstract View getView(Context c, int width, int height, Drawable placeHolder); @@ -454,5 +454,77 @@ abstract interface LocalData extends FilmStripView.ImageData { } } } + + /* + * A LocalData that does nothing but only shows a view. + */ + public static class LocalViewData implements LocalData { + private int mWidth; + private int mHeight; + View mView; + private long mDateTaken; + private long mDateModified; + + public LocalViewData(View v, + int width, int height, + int dateTaken, int dateModified) { + mView = v; + mWidth = width; + mHeight = height; + mDateTaken = dateTaken; + mDateModified = dateModified; + } + + @Override + public long getDateTaken() { + return mDateTaken; + } + + @Override + public long getDateModified() { + return mDateModified; + } + + @Override + public String getTitle() { + return ""; + } + + @Override + public int getWidth() { + return mWidth; + } + + @Override + public int getHeight() { + return mHeight; + } + + @Override + public int getType() { + return FilmStripView.ImageData.TYPE_PHOTO; + } + + @Override + public boolean isActionSupported(int action) { + if (action == FilmStripView.ImageData.ACTION_PLAY) return true; + return false; + } + + @Override + public View getView(Context c, int width, int height, Drawable placeHolder) { + return mView; + } + + @Override + public void prepare() { + // do nothing. + } + + @Override + public void recycle() { + // do nothing. + } + } } |