summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/ui
diff options
context:
space:
mode:
authorSanthosh Kumar H E <skhara@codeaurora.org>2013-12-05 16:36:52 +0530
committerSanthosh Kumar H E <skhara@codeaurora.org>2013-12-06 18:58:24 +0530
commitdbdb7620da136374eea95170261032f910015db0 (patch)
tree007242cdb44941ecb855751c85da69aa97cc6a43 /src/com/android/camera/ui
parent1c7734057201ffd1b6d165d9e24793ef3d213043 (diff)
parentdf2b0819907c440a660e228414a18184732816d1 (diff)
downloadandroid_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.java23
-rw-r--r--src/com/android/camera/ui/FilmStripView.java53
-rw-r--r--src/com/android/camera/ui/PieRenderer.java59
-rw-r--r--src/com/android/camera/ui/ProgressRenderer.java127
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;
+ }
+}