diff options
author | Paul Rohde <codelogic@google.com> | 2014-12-05 12:17:15 -0800 |
---|---|---|
committer | Paul Rohde <codelogic@google.com> | 2014-12-17 10:46:54 -0800 |
commit | 987ee64612e2510004fdf08536746c87234d01c1 (patch) | |
tree | 453d22c3c2548eecaa9e23c2a6e0bcbe1482b949 /src/com/android/camera/one | |
parent | b79279f49e365cc6da75c1bc44b4c786036d0aa7 (diff) | |
download | android_packages_apps_Camera2-987ee64612e2510004fdf08536746c87234d01c1.tar.gz android_packages_apps_Camera2-987ee64612e2510004fdf08536746c87234d01c1.tar.bz2 android_packages_apps_Camera2-987ee64612e2510004fdf08536746c87234d01c1.zip |
Drop new focus indicator into Camera2.
* Create a new custom focus view that interacts with physical lens diopter changes.
* Replace all occurances of the old focus indicator with the new one.
Change-Id: Ia02646ce4d1eb059ecb8a1dfccc15dfc9c167e1b
Diffstat (limited to 'src/com/android/camera/one')
7 files changed, 155 insertions, 57 deletions
diff --git a/src/com/android/camera/one/AbstractOneCamera.java b/src/com/android/camera/one/AbstractOneCamera.java index 15276ecca..b9514b96f 100644 --- a/src/com/android/camera/one/AbstractOneCamera.java +++ b/src/com/android/camera/one/AbstractOneCamera.java @@ -32,6 +32,7 @@ import java.util.TimeZone; public abstract class AbstractOneCamera implements OneCamera { protected FocusStateListener mFocusStateListener; protected ReadyStateChangedListener mReadyStateChangedListener; + protected FocusDistanceListener mFocusDistanceListener; /** * Number of characters from the end of the device serial number used to @@ -45,6 +46,11 @@ public abstract class AbstractOneCamera implements OneCamera { } @Override + public void setFocusDistanceListener(FocusDistanceListener listener) { + mFocusDistanceListener = listener; + } + + @Override public void setReadyStateChangedListener(ReadyStateChangedListener listener) { mReadyStateChangedListener = listener; } diff --git a/src/com/android/camera/one/OneCamera.java b/src/com/android/camera/one/OneCamera.java index a45f83433..d4700717a 100644 --- a/src/com/android/camera/one/OneCamera.java +++ b/src/com/android/camera/one/OneCamera.java @@ -208,6 +208,33 @@ public interface OneCamera { } /** + * Classes implementing this interface will be called when the focus + * distance of the physical lens changes. + */ + public static interface FocusDistanceListener { + /** + * Called when physical lens distance on the camera changes. + * + * @param diopter the lens diopter from the last known position. + * @param isActive whether the lens is moving. + */ + public void onFocusDistance(float diopter, boolean isActive); + } + + /** + * Single instance of the current camera AF state. + */ + public static class FocusState { + public final float diopter; + public final boolean isActive; + + public FocusState(float diopter, boolean isActive) { + this.diopter = diopter; + this.isActive = isActive; + } + } + + /** * Parameters to be given to capture requests. */ public static abstract class CaptureParameters { @@ -333,6 +360,12 @@ public interface OneCamera { public void setFocusStateListener(FocusStateListener listener); /** + * Sets or replaces a listener that is called whenever the focus state of + * the camera changes. + */ + public void setFocusDistanceListener(FocusDistanceListener listener); + + /** * Sets or replaces a listener that is called whenever the state of the * camera changes to be either ready or not ready to take another picture. */ diff --git a/src/com/android/camera/one/v2/ImageCaptureManager.java b/src/com/android/camera/one/v2/ImageCaptureManager.java index 4240a893d..09b3e180a 100644 --- a/src/com/android/camera/one/v2/ImageCaptureManager.java +++ b/src/com/android/camera/one/v2/ImageCaptureManager.java @@ -432,42 +432,7 @@ public class ImageCaptureManager extends CameraCaptureSession.CaptureCallback im @Override public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, final CaptureResult partialResult) { - long frameNumber = partialResult.getFrameNumber(); - - // Update mMetadata for whichever keys are present, if this frame is - // supplying newer values. - for (final Key<?> key : partialResult.getKeys()) { - Pair<Long, Object> oldEntry = mMetadata.get(key); - final Object oldValue = (oldEntry != null) ? oldEntry.second : null; - - boolean newerValueAlreadyExists = oldEntry != null - && frameNumber < oldEntry.first; - if (newerValueAlreadyExists) { - continue; - } - - final Object newValue = partialResult.get(key); - mMetadata.put(key, new Pair<Long, Object>(frameNumber, newValue)); - - // If the value has changed, call the appropriate listeners, if - // any exist. - if (oldValue == newValue || !mMetadataChangeListeners.containsKey(key)) { - continue; - } - - for (final MetadataChangeListener listener : - mMetadataChangeListeners.get(key)) { - Log.v(TAG, "Dispatching to metadata change listener for key: " - + key.toString()); - mListenerHandler.post(new Runnable() { - @Override - public void run() { - listener.onImageMetadataChange(key, oldValue, newValue, - partialResult); - } - }); - } - } + updateMetadataChangeListeners(partialResult); } @Override @@ -475,6 +440,8 @@ public class ImageCaptureManager extends CameraCaptureSession.CaptureCallback im final TotalCaptureResult result) { final long timestamp = result.get(TotalCaptureResult.SENSOR_TIMESTAMP); + updateMetadataChangeListeners(result); + // Detect camera thread stall. long now = SystemClock.uptimeMillis(); if (now - mDebugLastOnCaptureCompletedMillis < DEBUG_INTERFRAME_STALL_WARNING) { @@ -497,6 +464,43 @@ public class ImageCaptureManager extends CameraCaptureSession.CaptureCallback im tryExecutePendingCaptureRequest(timestamp); } + private void updateMetadataChangeListeners(final CaptureResult result) { + long frameNumber = result.getFrameNumber(); + + // Update mMetadata for whichever keys are present, if this frame is + // supplying newer values. + for (final Key<?> key : result.getKeys()) { + Pair<Long, Object> oldEntry = mMetadata.get(key); + final Object oldValue = (oldEntry != null) ? oldEntry.second : null; + + boolean newerValueAlreadyExists = oldEntry != null + && frameNumber < oldEntry.first; + if (newerValueAlreadyExists) { + continue; + } + + final Object newValue = result.get(key); + mMetadata.put(key, new Pair<Long, Object>(frameNumber, newValue)); + + // If the value has changed, call the appropriate listeners, if + // any exist. + if (oldValue == newValue || !mMetadataChangeListeners.containsKey(key)) { + continue; + } + + for (final MetadataChangeListener listener : + mMetadataChangeListeners.get(key)) { + mListenerHandler.post(new Runnable() { + @Override + public void run() { + listener.onImageMetadataChange(key, oldValue, newValue, + result); + } + }); + } + } + } + private boolean doMetaDataSwap(final TotalCaptureResult newMetadata, final long timestamp) { mEvictionHandler.get().onFrameCaptureResultAvailable(timestamp, newMetadata); diff --git a/src/com/android/camera/one/v2/OneCameraImpl.java b/src/com/android/camera/one/v2/OneCameraImpl.java index d70c3183b..2837f626c 100644 --- a/src/com/android/camera/one/v2/OneCameraImpl.java +++ b/src/com/android/camera/one/v2/OneCameraImpl.java @@ -223,6 +223,11 @@ public class OneCameraImpl extends AbstractOneCamera { AutoFocusHelper.logExtraFocusInfo(result); } + Float diopter = result.get(CaptureResult.LENS_FOCUS_DISTANCE); + if(diopter != null && mFocusDistanceListener != null) { + mFocusDistanceListener.onFocusDistance(diopter, true); + } + if (request.getTag() == RequestTag.CAPTURE) { // Add the capture result to the latest in-flight // capture. If all the data for that capture is diff --git a/src/com/android/camera/one/v2/OneCameraZslImpl.java b/src/com/android/camera/one/v2/OneCameraZslImpl.java index 97faf0f83..d53e89452 100644 --- a/src/com/android/camera/one/v2/OneCameraZslImpl.java +++ b/src/com/android/camera/one/v2/OneCameraZslImpl.java @@ -355,6 +355,27 @@ public class OneCameraZslImpl extends AbstractOneCamera { mMediaActionSound.load(MediaActionSound.SHUTTER_CLICK); } + @Override + public void setFocusDistanceListener(FocusDistanceListener focusDistanceListener) { + if(mFocusDistanceListener == null) { + mCaptureManager.addMetadataChangeListener(CaptureResult.LENS_FOCUS_DISTANCE, + new ImageCaptureManager.MetadataChangeListener() { + @Override + public void onImageMetadataChange(Key<?> key, Object oldValue, + Object newValue, + CaptureResult result) { + Integer state = result.get(CaptureResult.LENS_STATE); + if (newValue != null && state != null) { + mFocusDistanceListener.onFocusDistance((float) newValue, state == 1); + } else if (newValue != null) { + mFocusDistanceListener.onFocusDistance((float) newValue, true); + } + } + }); + } + mFocusDistanceListener = focusDistanceListener; + } + /** * @return The largest supported picture size. */ diff --git a/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java b/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java index 813ca9c66..e48d35715 100644 --- a/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java +++ b/src/com/android/camera/one/v2/SimpleJpegOneCameraFactory.java @@ -16,18 +16,6 @@ package com.android.camera.one.v2; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - import android.graphics.ImageFormat; import android.graphics.Rect; import android.hardware.camera2.CameraCharacteristics; @@ -57,6 +45,7 @@ import com.android.camera.async.SafeCloseable; import com.android.camera.async.Updatable; import com.android.camera.one.CameraDirectionProvider; import com.android.camera.one.OneCamera; +import com.android.camera.one.OneCamera.FocusState; import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy; import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy; import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory; @@ -98,6 +87,18 @@ import com.android.camera.session.CaptureSession; import com.android.camera.util.ScopedFactory; import com.android.camera.util.Size; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + /** */ public class SimpleJpegOneCameraFactory { @@ -111,6 +112,7 @@ public class SimpleJpegOneCameraFactory { public final FutureResult<GenericOneCameraImpl.PictureTaker> pictureTaker; public final FutureResult<GenericOneCameraImpl.ManualAutoFocus> manualAutoFocus; public final ConcurrentState<Integer> afState; + public final ConcurrentState<FocusState> focusState; public final ConcurrentState<Boolean> readyState; public final ConcurrentState<Float> zoomState; public final ConcurrentState<Boolean> previewStartSuccess; @@ -123,6 +125,7 @@ public class SimpleJpegOneCameraFactory { FutureResult<GenericOneCameraImpl.PictureTaker> pictureTaker, FutureResult<GenericOneCameraImpl.ManualAutoFocus> manualAutoFocus, ConcurrentState<Integer> afState, + ConcurrentState<FocusState> focusState, ConcurrentState<Boolean> readyState, ConcurrentState<Float> zoomState, ConcurrentState<Boolean> previewStartSuccess, Size pictureSize) { @@ -132,6 +135,7 @@ public class SimpleJpegOneCameraFactory { this.pictureTaker = pictureTaker; this.manualAutoFocus = manualAutoFocus; this.afState = afState; + this.focusState = focusState; this.readyState = readyState; this.zoomState = zoomState; this.previewStartSuccess = previewStartSuccess; @@ -175,12 +179,13 @@ public class SimpleJpegOneCameraFactory { FutureResult<GenericOneCameraImpl.PictureTaker> pictureTakerFutureResult = new FutureResult<>(); FutureResult<GenericOneCameraImpl.ManualAutoFocus> manualAutoFocusFutureResult = new FutureResult<>(); ConcurrentState<Integer> afState = new ConcurrentState<>(); + ConcurrentState<FocusState> focusState = new ConcurrentState<>(); ConcurrentState<Boolean> readyState = new ConcurrentState<>(); ConcurrentState<Float> zoomState = new ConcurrentState<>(); ConcurrentState<Boolean> previewStartSuccess = new ConcurrentState<>(); return new CameraScope(device, characteristics, mainHandler, pictureTakerFutureResult, - manualAutoFocusFutureResult, afState, + manualAutoFocusFutureResult, afState, focusState, readyState, zoomState, previewStartSuccess, pictureSize); } @@ -216,6 +221,10 @@ public class SimpleJpegOneCameraFactory { return new ListenableConcurrentState<>(scope.afState, provideMainHandlerExecutor(scope)); } + private static Listenable<FocusState> provideFocusStateListenable(CameraScope scope) { + return new ListenableConcurrentState<>(scope.focusState, provideMainHandlerExecutor(scope)); + } + private static Listenable<Boolean> provideReadyStateListenable(CameraScope scope) { return new ListenableConcurrentState<>(scope.readyState, provideMainHandlerExecutor(scope)); } @@ -519,6 +528,7 @@ public class SimpleJpegOneCameraFactory { GenericOneCameraImpl.PictureTaker pictureTaker = providePictureTaker(scope); GenericOneCameraImpl.ManualAutoFocus manualAutoFocus = provideManualAutoFocus(scope); Listenable<Integer> afStateListenable = provideAFStateListenable(scope); + Listenable<FocusState> focusStateListenable = provideFocusStateListenable(scope); Listenable<Boolean> readyStateListenable = provideReadyStateListenable(scope); float maxZoom = provideMaxZoom(scope.characteristics); Updatable<Float> zoom = provideZoom(scope); @@ -530,7 +540,7 @@ public class SimpleJpegOneCameraFactory { Listenable<Boolean> previewStartSuccessListenable = providePreviewStartSuccessListenable(scope); return new GenericOneCameraImpl(closeListeners, pictureTaker, manualAutoFocus, - afStateListenable, readyStateListenable, maxZoom, zoom, + afStateListenable, focusStateListenable, readyStateListenable, maxZoom, zoom, supportedPreviewSizes, fullSizeAspectRatio, direction, previewSizeSelector, previewStartSuccessListenable, surfaceRunnableScopedFactory); } diff --git a/src/com/android/camera/one/v2/common/GenericOneCameraImpl.java b/src/com/android/camera/one/v2/common/GenericOneCameraImpl.java index a19fd2844..1357b5cae 100644 --- a/src/com/android/camera/one/v2/common/GenericOneCameraImpl.java +++ b/src/com/android/camera/one/v2/common/GenericOneCameraImpl.java @@ -16,9 +16,6 @@ package com.android.camera.one.v2.common; -import java.util.HashSet; -import java.util.Set; - import android.content.Context; import android.view.Surface; @@ -32,6 +29,9 @@ import com.android.camera.util.Callback; import com.android.camera.util.ScopedFactory; import com.android.camera.util.Size; +import java.util.HashSet; +import java.util.Set; + /** * A generic, composable {@link OneCamera}. * <p> @@ -61,6 +61,7 @@ public class GenericOneCameraImpl implements OneCamera { private final PictureTaker mPictureTaker; private final ManualAutoFocus mManualAutoFocus; private final Listenable<Integer> mAFStateListenable; + private final Listenable<FocusState> mFocusStateListenable; private final Listenable<Boolean> mReadyStateListenable; private final float mMaxZoom; private final Updatable<Float> mZoom; @@ -71,10 +72,17 @@ public class GenericOneCameraImpl implements OneCamera { private final Listenable<Boolean> mPreviewStartSuccessListenable; private final ScopedFactory<Surface, Runnable> mPreviewScopeEntrance; - public GenericOneCameraImpl(Set<SafeCloseable> closeListeners, PictureTaker pictureTaker, - ManualAutoFocus manualAutoFocus, Listenable<Integer> afStateProvider, - Listenable<Boolean> readyStateListenable, float maxZoom, Updatable<Float> zoom, - Size[] supportedPreviewSizes, float fullSizeAspectRatio, Facing direction, + public GenericOneCameraImpl(Set<SafeCloseable> closeListeners, + PictureTaker pictureTaker, + ManualAutoFocus manualAutoFocus, + Listenable<Integer> afStateProvider, + Listenable<FocusState> focusStateProvider, + Listenable<Boolean> readyStateListenable, + float maxZoom, + Updatable<Float> zoom, + Size[] supportedPreviewSizes, + float fullSizeAspectRatio, + Facing direction, PreviewSizeSelector previewSizeSelector, Listenable<Boolean> previewStartSuccessListenable, ScopedFactory<Surface, Runnable> previewScopeEntrance) { @@ -89,6 +97,7 @@ public class GenericOneCameraImpl implements OneCamera { mPictureTaker = pictureTaker; mManualAutoFocus = manualAutoFocus; mAFStateListenable = afStateProvider; + mFocusStateListenable = focusStateProvider; mReadyStateListenable = readyStateListenable; mZoom = zoom; } @@ -128,6 +137,16 @@ public class GenericOneCameraImpl implements OneCamera { } @Override + public void setFocusDistanceListener(final FocusDistanceListener listener) { + mFocusStateListenable.setCallback(new Callback<FocusState>() { + @Override + public void onCallback(FocusState focusState) { + listener.onFocusDistance(focusState.diopter, focusState.isActive); + } + }); + } + + @Override public void setReadyStateChangedListener(final ReadyStateChangedListener listener) { mReadyStateListenable.setCallback(new Callback<Boolean>() { @Override |