OSDN Git Service

In 3A debug mode, show pass/fail for active scans and show exact AF, AE regions.
authorAndy Huibers <andyhuibers@google.com>
Tue, 26 Aug 2014 18:16:59 +0000 (11:16 -0700)
committerAndy Huibers <andyhuibers@google.com>
Tue, 26 Aug 2014 21:48:18 +0000 (14:48 -0700)
Bug: 17028594
Change-Id: I9c85178926a68c5e3ce26d04107db65514d84169

res/values/colors.xml
res/values/dimens.xml
src/com/android/camera/FocusOverlayManager.java
src/com/android/camera/ui/FaceView.java
src/com/android/camera/ui/FocusOverlay.java

index 8b6ee22..a70d443 100644 (file)
     <color name="bright_foreground_disabled_holo_dark">#ff4c4c4c</color>
     <color name="bright_foreground_holo_dark">#fff3f3f3</color>
     <color name="face_detect_start">#ffffff00</color>
-    <color name="face_detect_success">#8050d060</color>
-    <color name="face_detect_fail">#80d05060</color>
+    <color name="focus_debug">#90ffffff</color>
+    <color name="focus_debug_light">#50ffffff</color>
+    <color name="focus_debug_success">#9000ff00</color>
+    <color name="focus_debug_fail">#90ff0000</color>
     <color name="gray">#FFAAAAAA</color>
 
     <!-- Camera mode switcher -->
index 19c0e8a..c1aa989 100644 (file)
@@ -93,6 +93,7 @@
     <dimen name="focus_inner_stroke">2dp</dimen>
     <dimen name="switcher_size">72dp</dimen>
     <dimen name="face_circle_stroke">1dip</dimen>
+    <dimen name="focus_debug_stroke">1dip</dimen>
     <dimen name="shutter_offset">-22dp</dimen>
     <dimen name="size_thumbnail">200dip</dimen>
     <dimen name="size_preview">400dip</dimen>
index fde7207..efc5ac4 100644 (file)
@@ -68,6 +68,15 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
 
     private static final int RESET_TOUCH_FOCUS = 0;
     private static final int RESET_TOUCH_FOCUS_DELAY = 4000;
+    /**
+     * Size of AF region as multiple of shortest edge.
+     * Was 0.125 * longest edge prior to L release.
+     * TODO: Move to GservicesHelper
+     */
+    private static final float AF_REGION_BOX = 0.2f;
+
+    /** How much wider the touch metering area is relative to the AF area. */
+    public static final float AE_MULTIPLIER = 1.5f;
 
     private int mState = STATE_IDLE;
     private static final int STATE_IDLE = 0; // Focus is not active.
@@ -108,6 +117,7 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
     public  interface FocusUI {
         public boolean hasFaces();
         public void clearFocus();
+        public void setFocusPosition(int x, int y, boolean isPassiveScan, int aFsize, int aEsize);
         public void setFocusPosition(int x, int y, boolean isPassiveScan);
         public void onFocusStarted();
         public void onFocusSucceeded();
@@ -323,7 +333,8 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
         // animate on false->true trasition only b/8219520
         if (moving && !mPreviousMoving) {
             // Auto focus at the center of the preview.
-            mUI.setFocusPosition(mPreviewRect.centerX(), mPreviewRect.centerY(), true);
+            mUI.setFocusPosition(mPreviewRect.centerX(), mPreviewRect.centerY(), true,
+                    getAFRegionEdge(), getAERegionEdge());
             mUI.onFocusStarted();
         } else if (!moving) {
             mUI.onFocusSucceeded();
@@ -331,6 +342,20 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
         mPreviousMoving = moving;
     }
 
+    /** Returns width of auto focus region in pixels. */
+    private int getAFRegionEdge() {
+        return (int) (Math.min(mPreviewRect.width(), mPreviewRect.height()) * AF_REGION_BOX);
+    }
+
+    /** Returns width of metering region in pixels. */
+    private int getAERegionEdge() {
+        // Convert the coordinates to driver format.
+        // AE area is bigger by AE_MULTIPLIER because exposure is sensitive and
+        // easy to over- or underexposure if area is too small.
+        return (int) (Math.min(mPreviewRect.width(), mPreviewRect.height()) * AF_REGION_BOX
+                * AE_MULTIPLIER);
+    }
+
     @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
     private void initializeFocusAreas(int x, int y) {
         if (mFocusArea == null) {
@@ -339,7 +364,7 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
         }
 
         // Convert the coordinates to driver format.
-        calculateTapArea(x, y, 1f, mFocusArea.get(0).rect);
+        calculateTapArea(x, y, getAFRegionEdge(), mFocusArea.get(0).rect);
     }
 
     @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@@ -350,9 +375,7 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
         }
 
         // Convert the coordinates to driver format.
-        // AE area is bigger because exposure is sensitive and
-        // easy to over- or underexposure if area is too small.
-        calculateTapArea(x, y, 1.5f, mMeteringArea.get(0).rect);
+        calculateTapArea(x, y, getAERegionEdge(), mMeteringArea.get(0).rect);
     }
 
     public void onSingleTapUp(int x, int y) {
@@ -379,7 +402,7 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
         }
 
         // Use margin to set the focus indicator to the touched area.
-        mUI.setFocusPosition(x, y, false);
+        mUI.setFocusPosition(x, y, false, getAFRegionEdge(), getAERegionEdge());
         // Log manual tap to focus.
         mTouchCoordinate = new TouchCoordinate(x, y, mPreviewRect.width(), mPreviewRect.height());
         mTouchTime = System.currentTimeMillis();
@@ -575,24 +598,17 @@ public class FocusOverlayManager implements PreviewStatusListener.PreviewAreaCha
         }
     }
 
-    private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) {
-        int areaSize = (int) (getAreaSize() * areaMultiple);
-        int left = CameraUtil.clamp(x - areaSize / 2, mPreviewRect.left,
-                mPreviewRect.right - areaSize);
-        int top = CameraUtil.clamp(y - areaSize / 2, mPreviewRect.top,
-                mPreviewRect.bottom - areaSize);
+    private void calculateTapArea(int x, int y, int size, Rect rect) {
+        int left = CameraUtil.clamp(x - size / 2, mPreviewRect.left,
+                mPreviewRect.right - size);
+        int top = CameraUtil.clamp(y - size / 2, mPreviewRect.top,
+                mPreviewRect.bottom - size);
 
-        RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
+        RectF rectF = new RectF(left, top, left + size, top + size);
         mMatrix.mapRect(rectF);
         CameraUtil.rectFToRect(rectF, rect);
     }
 
-    private int getAreaSize() {
-        // Recommended focus area size from the manufacture is 1/8 of the image
-        // width (i.e. longer edge of the image)
-        return Math.max(mPreviewRect.width(), mPreviewRect.height()) / 8;
-    }
-
     /* package */ int getFocusState() {
         return mState;
     }
index 144031f..898e00a 100644 (file)
@@ -53,9 +53,6 @@ public class FaceView extends View
     private Face[] mFaces;
     private Face[] mPendingFaces;
     private int mColor;
-    private final int mFocusingColor;
-    private final int mFocusedColor;
-    private final int mFailColor;
     private Paint mPaint;
     private volatile boolean mBlocked;
 
@@ -79,10 +76,7 @@ public class FaceView extends View
     public FaceView(Context context, AttributeSet attrs) {
         super(context, attrs);
         Resources res = getResources();
-        mFocusingColor = res.getColor(R.color.face_detect_start);
-        mFocusedColor = res.getColor(R.color.face_detect_success);
-        mFailColor = res.getColor(R.color.face_detect_fail);
-        mColor = mFocusingColor;
+        mColor = res.getColor(R.color.face_detect_start);
         mPaint = new Paint();
         mPaint.setAntiAlias(true);
         mPaint.setStyle(Style.STROKE);
@@ -139,21 +133,18 @@ public class FaceView extends View
 
     @Override
     public void showStart() {
-        mColor = mFocusingColor;
         invalidate();
     }
 
     // Ignore the parameter. No autofocus animation for face detection.
     @Override
     public void showSuccess(boolean timeout) {
-        mColor = mFocusedColor;
         invalidate();
     }
 
     // Ignore the parameter. No autofocus animation for face detection.
     @Override
     public void showFail(boolean timeout) {
-        mColor = mFailColor;
         invalidate();
     }
 
@@ -161,7 +152,6 @@ public class FaceView extends View
     public void clear() {
         // Face indicator is displayed during preview. Do not clear the
         // drawable.
-        mColor = mFocusingColor;
         mFaces = null;
         invalidate();
     }
index 46f640c..d9b233a 100644 (file)
@@ -18,13 +18,16 @@ package com.android.camera.ui;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
 
 import com.android.camera.FocusOverlayManager;
+import com.android.camera.debug.DebugPropertyHelper;
 import com.android.camera.debug.Log;
 import com.android.camera2.R;
 
@@ -34,14 +37,27 @@ import com.android.camera2.R;
 public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
     private static final Log.Tag TAG = new Log.Tag("FocusOverlay");
 
+    /** System Properties switch to enable debugging focus UI. */
+    private static final boolean CAPTURE_DEBUG_UI = DebugPropertyHelper.showCaptureDebugUI();
+
     private final static int FOCUS_DURATION_MS = 500;
     private final static int FOCUS_INDICATOR_ROTATION_DEGREES = 50;
 
     private final Drawable mFocusIndicator;
-    private final Drawable mFocusOuterRing;
+    private Drawable mFocusOuterRing;
     private final Rect mBounds = new Rect();
     private final ValueAnimator mFocusAnimation = new ValueAnimator();
 
+    private Paint mDebugPaint;
+    private Paint mDebugAEPaint;
+    private int mDebugStartColor;
+    private int mDebugPassiveColor;
+    private int mDebugSuccessColor;
+    private int mDebugFailColor;
+    private Rect mFocusDebugAFRect;
+    private Rect mFocusDebugAERect;
+    private boolean mIsPassiveScan;
+
     private int mPositionX;
     private int mPositionY;
     private int mAngle;
@@ -55,6 +71,23 @@ public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
         mFocusIndicatorSize = getResources().getDimensionPixelSize(R.dimen.focus_inner_ring_size);
         mFocusOuterRing = getResources().getDrawable(R.drawable.focus_ring_touch_outer);
         mFocusOuterRingSize = getResources().getDimensionPixelSize(R.dimen.focus_outer_ring_size);
+
+        if (CAPTURE_DEBUG_UI) {
+            Resources res = getResources();
+            mDebugStartColor = res.getColor(R.color.focus_debug);
+            mDebugPassiveColor = res.getColor(R.color.focus_debug_light);
+            mDebugSuccessColor = res.getColor(R.color.focus_debug_success);
+            mDebugFailColor = res.getColor(R.color.focus_debug_fail);
+            mDebugPaint = new Paint();
+            mDebugPaint.setColor(res.getColor(R.color.focus_debug));
+            mDebugPaint.setAntiAlias(true);
+            mDebugPaint.setStyle(Paint.Style.STROKE);
+            mDebugPaint.setStrokeWidth(res.getDimension(R.dimen.focus_debug_stroke));
+            mDebugAEPaint = new Paint(mDebugPaint);
+            mDebugAEPaint.setColor(res.getColor(R.color.focus_debug));
+            mFocusDebugAFRect = new Rect();
+            mFocusDebugAERect = new Rect();
+        }
     }
 
     @Override
@@ -66,10 +99,19 @@ public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
     @Override
     public void clearFocus() {
         mShowIndicator = false;
+        if (CAPTURE_DEBUG_UI) {
+            setVisibility(INVISIBLE);
+        }
     }
 
     @Override
     public void setFocusPosition(int x, int y, boolean isPassiveScan) {
+        setFocusPosition(x, y, isPassiveScan, 0, 0);
+    }
+
+    @Override
+    public void setFocusPosition(int x, int y, boolean isPassiveScan, int aFsize, int aEsize) {
+        mIsPassiveScan = isPassiveScan;
         mPositionX = x;
         mPositionY = y;
         mBounds.set(x - mFocusIndicatorSize / 2, y - mFocusIndicatorSize / 2,
@@ -77,6 +119,20 @@ public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
         mFocusIndicator.setBounds(mBounds);
         mFocusOuterRing.setBounds(x - mFocusOuterRingSize / 2, y - mFocusOuterRingSize / 2,
                 x + mFocusOuterRingSize / 2, y + mFocusOuterRingSize / 2);
+
+        if (CAPTURE_DEBUG_UI) {
+            mFocusOuterRing.setBounds(0, 0, 0, 0);
+            mFocusDebugAFRect.set(x - aFsize / 2, y - aFsize / 2, x + aFsize / 2, y + aFsize / 2);
+            // If AE region is different size than AF region and active scan.
+            if (aFsize != aEsize && !isPassiveScan) {
+                mFocusDebugAERect.set(x - aEsize / 2, y - aEsize / 2, x + aEsize / 2,
+                        y + aEsize / 2);
+            } else {
+                mFocusDebugAERect.set(0, 0, 0, 0);
+            }
+            mDebugPaint.setColor(isPassiveScan ? mDebugPassiveColor : mDebugStartColor);
+        }
+
         if (getVisibility() != VISIBLE) {
             setVisibility(VISIBLE);
         }
@@ -101,6 +157,9 @@ public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
     public void onFocusSucceeded() {
         mFocusAnimation.cancel();
         mShowIndicator = false;
+        if (CAPTURE_DEBUG_UI && !mIsPassiveScan) {
+            mDebugPaint.setColor(mDebugSuccessColor);
+        }
         invalidate();
     }
 
@@ -108,6 +167,9 @@ public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
     public void onFocusFailed() {
         mFocusAnimation.cancel();
         mShowIndicator = false;
+        if (CAPTURE_DEBUG_UI && !mIsPassiveScan) {
+            mDebugPaint.setColor(mDebugFailColor);
+        }
         invalidate();
     }
 
@@ -132,5 +194,18 @@ public class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
             mFocusIndicator.draw(canvas);
             canvas.restore();
         }
+        if (CAPTURE_DEBUG_UI && mFocusDebugAFRect != null) {
+            canvas.drawRect(mFocusDebugAFRect, mDebugPaint);
+            float delta = 0.1f * mFocusDebugAERect.width();
+            float left = mFocusDebugAERect.left;
+            float top = mFocusDebugAERect.top;
+            float right = mFocusDebugAERect.right;
+            float bot = mFocusDebugAERect.bottom;
+
+            canvas.drawLines(new float[]{left, top + delta, left, top, left, top, left + delta, top}, mDebugAEPaint);
+            canvas.drawLines(new float[]{right, top + delta, right, top, right, top, right - delta, top}, mDebugAEPaint);
+            canvas.drawLines(new float[]{left, bot - delta, left, bot, left, bot, left + delta, bot}, mDebugAEPaint);
+            canvas.drawLines(new float[]{right, bot - delta, right, bot, right, bot, right - delta, bot}, mDebugAEPaint);
+        }
     }
 }