diff options
author | Santhosh Kumar H E <skhara@codeaurora.org> | 2013-12-05 16:36:52 +0530 |
---|---|---|
committer | Santhosh Kumar H E <skhara@codeaurora.org> | 2013-12-06 18:58:24 +0530 |
commit | dbdb7620da136374eea95170261032f910015db0 (patch) | |
tree | 007242cdb44941ecb855751c85da69aa97cc6a43 /src/com/android/camera/ui | |
parent | 1c7734057201ffd1b6d165d9e24793ef3d213043 (diff) | |
parent | df2b0819907c440a660e228414a18184732816d1 (diff) | |
download | android_packages_apps_Snap-dbdb7620da136374eea95170261032f910015db0.tar.gz android_packages_apps_Snap-dbdb7620da136374eea95170261032f910015db0.tar.bz2 android_packages_apps_Snap-dbdb7620da136374eea95170261032f910015db0.zip |
Merge remote-tracking branch into merge_branch
Delay onResume tasks to speed up lockscreen onResume->onPause->onResume launch sequence.
Import translations. DO NOT MERGE
gcam: Clean up placeholders, and add deletion robustness.
Fix issue of focus indicator staying on without being hidden
Ensure view size gets updated after phone decors change.
Show the 100% state of the progress at least one frame.
Add parameters and deduplicate parameter changes
Revert parallel opening camera in photo mode.
Differentiate the InProgressData from the normal PhotoData.
Close mode menus if another control is touched
Start gcam module directly when handling capture intent.
Import translations. DO NOT MERGE
Add a null check to fix NPE
Add logging to various actions
Ensure mOpenCameraThread has been setup before dereferencing.
Add logging to various actions
Ensure mOpenCameraThread has been setup before dereferencing.
Add GCam progress indicator.
hide preview cover on arrival of new preview data if hidden
Fix photo mode is getting stuck in a single CameraState.
...
Conflicts:
res/layout/photo_module.xml
res/values/arrays.xml
src/com/android/camera/CameraActivity.java
src/com/android/camera/PhotoUI.java
src/com/android/camera/Storage.java
src/com/android/camera/WideAnglePanoramaModule.java
src/com/android/camera/ui/FilmStripView.java
Change-Id: Ic41b4e7e07b2b0ed7936b78a6c5f05270d05985f
Diffstat (limited to 'src/com/android/camera/ui')
-rw-r--r-- | src/com/android/camera/ui/CameraRootView.java | 23 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmStripView.java | 53 | ||||
-rw-r--r-- | src/com/android/camera/ui/PieRenderer.java | 59 | ||||
-rw-r--r-- | src/com/android/camera/ui/ProgressRenderer.java | 127 |
4 files changed, 220 insertions, 42 deletions
diff --git a/src/com/android/camera/ui/CameraRootView.java b/src/com/android/camera/ui/CameraRootView.java index 505549c80..daaefc027 100644 --- a/src/com/android/camera/ui/CameraRootView.java +++ b/src/com/android/camera/ui/CameraRootView.java @@ -37,7 +37,7 @@ public class CameraRootView extends FrameLayout { private int mBottomMargin = 0; private int mLeftMargin = 0; private int mRightMargin = 0; - private Rect mCurrentInsets; + private final Rect mCurrentInsets = new Rect(0, 0, 0, 0); private int mOffset = 0; private Object mDisplayListener; private MyDisplayListener mListener; @@ -53,19 +53,24 @@ public class CameraRootView extends FrameLayout { @Override protected boolean fitSystemWindows(Rect insets) { - mCurrentInsets = insets; // insets include status bar, navigation bar, etc // In this case, we are only concerned with the size of nav bar - if (mOffset > 0) { - return true; + if (mCurrentInsets.equals(insets)) { + // Local copy of the insets is up to date. No need to do anything. + return false; } - if (insets.bottom > 0) { - mOffset = insets.bottom; - } else if (insets.right > 0) { - mOffset = insets.right; + if (mOffset == 0) { + if (insets.bottom > 0) { + mOffset = insets.bottom; + } else if (insets.right > 0) { + mOffset = insets.right; + } } - return true; + mCurrentInsets.set(insets); + // Make sure onMeasure will be called to adapt to the new insets. + requestLayout(); + return false; } public void initDisplayListener() { diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index 9945952ee..89da0184e 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -43,6 +43,7 @@ import com.android.camera.ui.FilmStripView.ImageData.PanoramaSupportCallback; import com.android.camera.ui.FilmstripBottomControls.BottomControlsListener; import com.android.camera.util.CameraUtil; import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; +import com.android.camera.util.UsageStatistics; import com.android.camera2.R; import java.util.Arrays; @@ -1453,6 +1454,13 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { mController.setSurroundingViewsVisible(true); } + private void hideZoomView() { + if (mController.isZoomStarted()) { + mController.cancelLoadingZoomedImage(); + mZoomView.setVisibility(GONE); + } + } + // Keeps the view in the view hierarchy if it's camera preview. // Remove from the hierarchy otherwise. private void checkForRemoval(ImageData data, View v) { @@ -1785,6 +1793,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { && deltaX < mSlop * (-1)) { // intercept left swipe if (Math.abs(deltaX) >= Math.abs(deltaY) * 2) { + UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, + UsageStatistics.ACTION_FILMSTRIP, null); return true; } } @@ -1908,10 +1918,19 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { mController.stopScrolling(true); mController.stopScale(); mDataIdOnUserScrolling = 0; - // Remove all views from the mViewItem buffer, except the camera view. + // Reload has a side effect that after this call, it will show the + // camera preview. So we want to know whether it starts from the camera + // preview to decide whether we need to call onDataFocusChanged. + boolean stayInPreview = false; + if (mListener != null && mViewItem[mCurrentItem] != null) { - mListener.onDataFocusChanged(mViewItem[mCurrentItem].getId(), false); + stayInPreview = mViewItem[mCurrentItem].getId() == 0; + if (!stayInPreview) { + mListener.onDataFocusChanged(mViewItem[mCurrentItem].getId(), false); + } } + + // Remove all views from the mViewItem buffer, except the camera view. for (int i = 0; i < mViewItem.length; i++) { if (mViewItem[i] == null) { continue; @@ -1920,8 +1939,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (v != mCameraView) { removeView(v); } - if (mDataAdapter.getImageData(mViewItem[i].getId()) != null) { - mDataAdapter.getImageData(mViewItem[i].getId()).recycle(); + ImageData imageData = mDataAdapter.getImageData(mViewItem[i].getId()); + if (imageData != null) { + imageData.recycle(); } } @@ -1954,7 +1974,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (mListener != null) { mListener.onReload(); - mListener.onDataFocusChanged(mViewItem[mCurrentItem].getId(), true); + if (!stayInPreview) { + mListener.onDataFocusChanged(mViewItem[mCurrentItem].getId(), true); + } } } @@ -2625,13 +2647,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (!mController.stopScrolling(false)) { return false; } - // A down event is usually followed by a gesture, we apply gesture on - // the lower-res image during a gesture to ensure a responsive experience. - // TODO: Delay this until gesture starts. - if (mController.isZoomStarted()) { - mController.cancelLoadingZoomedImage(); - mZoomView.setVisibility(GONE); - } + return true; } @@ -2712,12 +2728,16 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onScroll(float x, float y, float dx, float dy) { - if (mViewItem[mCurrentItem] == null) { + ViewItem currItem = mViewItem[mCurrentItem]; + if (currItem == null) { return false; } + if (!mDataAdapter.canSwipeInFullScreen(currItem.getId())) { + return false; + } + hideZoomView(); // When image is zoomed in to be bigger than the screen if (mController.isZoomStarted()) { - mController.cancelLoadingZoomedImage(); ViewItem curr = mViewItem[mCurrentItem]; float transX = curr.getTranslationX() - dx; float transY = curr.getTranslationY() - dy; @@ -2777,6 +2797,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (currItem == null) { return false; } + if (!mDataAdapter.canSwipeInFullScreen(currItem.getId())) { + return false; + } if (mController.isZoomStarted()) { // Fling within the zoomed image mController.flingInsideZoomView(velocityX, velocityY); @@ -2837,6 +2860,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (inCameraFullscreen()) { return false; } + + hideZoomView(); mScaleTrend = 1f; // If the image is smaller than screen size, we should allow to zoom // in to full screen size diff --git a/src/com/android/camera/ui/PieRenderer.java b/src/com/android/camera/ui/PieRenderer.java index 008bc40ca..0039aa22c 100644 --- a/src/com/android/camera/ui/PieRenderer.java +++ b/src/com/android/camera/ui/PieRenderer.java @@ -16,9 +16,6 @@ package com.android.camera.ui; -import java.util.ArrayList; -import java.util.List; - import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.ValueAnimator; @@ -40,12 +37,19 @@ import android.view.animation.Animation; import android.view.animation.Transformation; import com.android.camera.drawable.TextDrawable; +import com.android.camera.ui.ProgressRenderer.VisibilityListener; import com.android.camera2.R; +import java.util.ArrayList; +import java.util.List; + +/** + * An overlay renderer that is used to display focus state and progress state. + */ public class PieRenderer extends OverlayRenderer implements FocusIndicator { - private static final String TAG = "CAM Pie"; + private static final String TAG = "PieRenderer"; // Sometimes continuous autofocus starts and stops several times quickly. // These states are used to make sure the animation is run for at least some @@ -143,7 +147,7 @@ public class PieRenderer extends OverlayRenderer private int mAngleZone; private float mCenterAngle; - + private ProgressRenderer mProgressRenderer; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { @@ -227,6 +231,7 @@ public class PieRenderer extends OverlayRenderer mLabel.setDropShadow(true); mDeadZone = res.getDimensionPixelSize(R.dimen.pie_deadzone_width); mAngleZone = res.getDimensionPixelSize(R.dimen.pie_anglezone_width); + mProgressRenderer = new ProgressRenderer(ctx); } private PieItem getRoot() { @@ -309,6 +314,10 @@ public class PieRenderer extends OverlayRenderer return mState == STATE_PIE && isVisible(); } + public void setProgress(int percent) { + mProgressRenderer.setProgress(percent); + } + private void fadeIn() { mFadeIn = new ValueAnimator(); mFadeIn.setFloatValues(0f, 1f); @@ -524,6 +533,8 @@ public class PieRenderer extends OverlayRenderer @Override public void onDraw(Canvas canvas) { + mProgressRenderer.onDraw(canvas, mFocusX, mFocusY); + float alpha = 1; if (mXFade != null) { alpha = (Float) mXFade.getAnimatedValue(); @@ -706,6 +717,11 @@ public class PieRenderer extends OverlayRenderer return false; } + @Override + public boolean isVisible() { + return super.isVisible() || mProgressRenderer.isVisible(); + } + private boolean pulledToCenter(PointF polarCoords) { return polarCoords.y < mArcRadius - mRadiusInc; } @@ -918,17 +934,6 @@ public class PieRenderer extends OverlayRenderer setCircle(mFocusX, mFocusY); } - public void alignFocus(int x, int y) { - mOverlay.removeCallbacks(mDisappear); - mAnimation.cancel(); - mAnimation.reset(); - mFocusX = x; - mFocusY = y; - mDialAngle = DIAL_HORIZONTAL; - setCircle(x, y); - mFocused = false; - } - public int getSize() { return 2 * mCircleSize; } @@ -1022,11 +1027,27 @@ public class PieRenderer extends OverlayRenderer mState = STATE_IDLE; } + public void clear(boolean waitUntilProgressIsHidden) { + if (mState == STATE_PIE) + return; + cancelFocus(); + + if (waitUntilProgressIsHidden) { + mProgressRenderer.setVisibilityListener(new VisibilityListener() { + @Override + public void onHidden() { + mOverlay.post(mDisappear); + } + }); + } else { + mOverlay.post(mDisappear); + mProgressRenderer.setVisibilityListener(null); + } + } + @Override public void clear() { - if (mState == STATE_PIE) return; - cancelFocus(); - mOverlay.post(mDisappear); + clear(false); } private void startAnimation(long duration, boolean timeout, diff --git a/src/com/android/camera/ui/ProgressRenderer.java b/src/com/android/camera/ui/ProgressRenderer.java new file mode 100644 index 000000000..500293133 --- /dev/null +++ b/src/com/android/camera/ui/ProgressRenderer.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.ui; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; + +import com.android.camera2.R; + +/** + * Renders a circular progress bar on the screen. + */ +public class ProgressRenderer { + + public static interface VisibilityListener { + public void onHidden(); + } + + private final int mProgressRadius; + private final Paint mProgressBasePaint; + private final Paint mProgressPaint; + + private RectF mArcBounds = new RectF(0, 0, 1, 1); + private int mProgressAngleDegrees = 270; + private boolean mVisible = false; + private VisibilityListener mVisibilityListener; + + /** + * After we reach 100%, keep on painting the progress for another x milliseconds + * before hiding it. + */ + private static final int SHOW_PROGRESS_X_ADDITIONAL_MS = 100; + + /** When to hide the progress indicator. */ + private long mTimeToHide = 0; + + public ProgressRenderer(Context context) { + mProgressRadius = context.getResources().getDimensionPixelSize(R.dimen.pie_progress_radius); + int pieProgressWidth = context.getResources().getDimensionPixelSize( + R.dimen.pie_progress_width); + mProgressBasePaint = createProgressPaint(pieProgressWidth, 0.2f); + mProgressPaint = createProgressPaint(pieProgressWidth, 1.0f); + } + + /** + * Sets or replaces a visiblity listener. + */ + public void setVisibilityListener(VisibilityListener listener) { + mVisibilityListener = listener; + } + + /** + * Shows a progress indicator. If the progress is '100', the progress + * indicator will be hidden. + * + * @param percent the progress in percent (0-100). + */ + public void setProgress(int percent) { + // Clamp the value. + percent = Math.min(100, Math.max(percent, 0)); + mProgressAngleDegrees = (int) ((360f / 100) * percent); + + // We hide the progress once we drew the 100% state once. + if (percent < 100) { + mVisible = true; + mTimeToHide = System.currentTimeMillis() + SHOW_PROGRESS_X_ADDITIONAL_MS; + } + } + + /** + * Draw the current progress (if < 100%) centered at the given location. + */ + public void onDraw(Canvas canvas, int centerX, int centerY) { + if (!mVisible) { + return; + } + mArcBounds = new RectF(centerX - mProgressRadius, centerY - mProgressRadius, centerX + + mProgressRadius, + centerY + mProgressRadius); + + canvas.drawCircle(centerX, centerY, mProgressRadius, mProgressBasePaint); + canvas.drawArc(mArcBounds, -90, mProgressAngleDegrees, false, mProgressPaint); + + // After we reached 100%, we paint the progress renderer for another x + // milliseconds until we hide it. + if (mProgressAngleDegrees == 360 && System.currentTimeMillis() > mTimeToHide) { + mVisible = false; + if (mVisibilityListener != null) { + mVisibilityListener.onHidden(); + } + } + } + + /** + * @return Whether the progress renderer is visible. + */ + public boolean isVisible() { + return mVisible; + } + + private static Paint createProgressPaint(int width, float alpha) { + Paint paint = new Paint(); + paint.setAntiAlias(true); + // 20% alpha. + paint.setColor(Color.argb((int) (alpha * 255), 255, 255, 255)); + paint.setStrokeWidth(width); + paint.setStyle(Paint.Style.STROKE); + return paint; + } +} |