1512001df0211fa8999593717a0f186457a5a9cefPuneet Lall/* 2512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Copyright (C) 2014 The Android Open Source Project 3512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 40ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 50ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * in compliance with the License. You may obtain a copy of the License at 6512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 70ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * http://www.apache.org/licenses/LICENSE-2.0 8512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 90ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * Unless required by applicable law or agreed to in writing, software distributed under the License 100ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 110ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * or implied. See the License for the specific language governing permissions and limitations under 120ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * the License. 13512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 14512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 15512001df0211fa8999593717a0f186457a5a9cefPuneet Lallpackage com.android.camera.one.v2; 16512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 17512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.annotation.TargetApi; 18512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.content.Context; 19512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.graphics.ImageFormat; 20512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.graphics.Rect; 21512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CameraAccessException; 22512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CameraCaptureSession; 23512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CameraCharacteristics; 24512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CameraDevice; 25512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CameraMetadata; 26512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CaptureRequest; 27512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.CaptureResult; 28580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lallimport android.hardware.camera2.CaptureResult.Key; 29512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.TotalCaptureResult; 30512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.params.MeteringRectangle; 31512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.hardware.camera2.params.StreamConfigurationMap; 32dfef32425e6184d5721bb7af9db823ec46bc2b4fSascha Haeberlingimport android.location.Location; 33512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.media.CameraProfile; 34512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.media.Image; 35512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.media.ImageReader; 3617d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibersimport android.media.MediaActionSound; 37512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.net.Uri; 38512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.os.Build; 39512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.os.Handler; 40512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.os.HandlerThread; 41580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lallimport android.os.SystemClock; 42512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.support.v4.util.Pools; 43512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport android.view.Surface; 44512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 45512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.CaptureModuleUtil; 46512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.debug.Log; 47512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.debug.Log.Tag; 48512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.exif.ExifInterface; 49512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.exif.ExifTag; 50512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.exif.Rational; 51512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.one.AbstractOneCamera; 529ceed0d5535e8453f8b5f77959134760dac01ec5Puneet Lallimport com.android.camera.one.CameraDirectionProvider; 53512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.one.OneCamera; 54512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.one.OneCamera.PhotoCaptureParameters.Flash; 55b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibersimport com.android.camera.one.Settings3A; 56512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.one.v2.ImageCaptureManager.ImageCaptureListener; 57580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lallimport com.android.camera.one.v2.ImageCaptureManager.MetadataChangeListener; 585ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lallimport com.android.camera.one.v2.camera2proxy.AndroidCaptureResultProxy; 5930ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Linimport com.android.camera.one.v2.camera2proxy.AndroidImageProxy; 60f6031c016d916db9789026dc0a6c559d8163a088Spike Spragueimport com.android.camera.one.v2.camera2proxy.CaptureResultProxy; 61f6031c016d916db9789026dc0a6c559d8163a088Spike Spragueimport com.android.camera.processing.imagebackend.TaskImageContainer; 62512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.session.CaptureSession; 63aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohdeimport com.android.camera.ui.focus.LensRangeCalculator; 64aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohdeimport com.android.camera.ui.motion.LinearScale; 65512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.util.CameraUtil; 66f6031c016d916db9789026dc0a6c559d8163a088Spike Spragueimport com.android.camera.util.ExifUtil; 67512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.util.JpegUtilNative; 6882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharimport com.android.camera.util.ListenerCombiner; 69512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport com.android.camera.util.Size; 70f6031c016d916db9789026dc0a6c559d8163a088Spike Spragueimport com.google.common.base.Optional; 7137036186326fb68c27063f97305405d3667a5eb3Sascha Haeberlingimport com.google.common.util.concurrent.FutureCallback; 7237036186326fb68c27063f97305405d3667a5eb3Sascha Haeberlingimport com.google.common.util.concurrent.Futures; 7337036186326fb68c27063f97305405d3667a5eb3Sascha Haeberlingimport com.google.common.util.concurrent.ListenableFuture; 74512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 75512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport java.nio.ByteBuffer; 760ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lallimport java.security.InvalidParameterException; 77512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport java.util.ArrayList; 78863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lallimport java.util.Collections; 79863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lallimport java.util.HashSet; 80512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport java.util.List; 81863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lallimport java.util.Set; 82512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport java.util.concurrent.LinkedBlockingQueue; 83512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport java.util.concurrent.ThreadPoolExecutor; 84512001df0211fa8999593717a0f186457a5a9cefPuneet Lallimport java.util.concurrent.TimeUnit; 85512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 86512001df0211fa8999593717a0f186457a5a9cefPuneet Lall/** 87512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * {@link OneCamera} implementation directly on top of the Camera2 API with zero 88512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * shutter lag.<br> 89512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * TODO: Determine what the maximum number of full YUV capture frames is. 90512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 9130ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin@TargetApi(Build.VERSION_CODES.LOLLIPOP) 92386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall@Deprecated 93512001df0211fa8999593717a0f186457a5a9cefPuneet Lallpublic class OneCameraZslImpl extends AbstractOneCamera { 94512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private static final Tag TAG = new Tag("OneCameraZslImpl2"); 95512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 96512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Default JPEG encoding quality. */ 970ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall private static final int JPEG_QUALITY = 980ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall CameraProfile.getJpegEncodingQualityParameter(CameraProfile.QUALITY_HIGH); 99512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 10082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * The maximum number of images to store in the full-size ZSL ring buffer. 101512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * <br> 102512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * TODO: Determine this number dynamically based on available memory and the 103512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * size of frames. 104512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 10582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar private static final int MAX_CAPTURE_IMAGES = 12; 106512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 107512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * True if zero-shutter-lag images should be captured. Some devices produce 108512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * lower-quality images for the high-frequency stream, so we may wish to 109512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * disable ZSL in that case. 110512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 111512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private static final boolean ZSL_ENABLED = true; 112512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 113512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 114580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * Tags which may be used in CaptureRequests. 115580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 116580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private static enum RequestTag { 117580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 118580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * Indicates that the request was explicitly sent for a single 119580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * high-quality still capture. Unlike other requests, such as the 120580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * repeating (ZSL) stream and AF/AE triggers, requests with this tag 121580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * should always be saved. 122580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 123580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall EXPLICIT_CAPTURE 124182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall } 125580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 126580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 127512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Set to ImageFormat.JPEG to use the hardware encoder, or 128512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * ImageFormat.YUV_420_888 to use the software encoder. No other image 129512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * formats are supported. 130512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 131512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private static final int sCaptureImageFormat = ImageFormat.YUV_420_888; 132580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 133182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * Token for callbacks posted to {@link #mCameraHandler} to resume 134182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * continuous AF. 135580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 136580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private static final String FOCUS_RESUME_CALLBACK_TOKEN = "RESUME_CONTINUOUS_AF"; 1379cefdd495332719d987ffb942742ec602793d8d4Jiawen Chen 138512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Zero weight 3A region, to reset regions per API. */ 1399cefdd495332719d987ffb942742ec602793d8d4Jiawen Chen /*package*/ MeteringRectangle[] ZERO_WEIGHT_3A_REGION = AutoFocusHelper.getZeroWeightRegion(); 140512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 141580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 142580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * Thread on which high-priority camera operations, such as grabbing preview 143580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * frames for the viewfinder, are running. 144580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 145512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private final HandlerThread mCameraThread; 146512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Handler of the {@link #mCameraThread}. */ 147512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private final Handler mCameraHandler; 148512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 149580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** Thread on which low-priority camera listeners are running. */ 150580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private final HandlerThread mCameraListenerThread; 151580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private final Handler mCameraListenerHandler; 152580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 153512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** The characteristics of this camera. */ 154512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private final CameraCharacteristics mCharacteristics; 155aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde /** Converts focus distance units into ratio values */ 156aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde private final LinearScale mLensRange; 157512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** The underlying Camera2 API camera device. */ 158512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private final CameraDevice mDevice; 1599ceed0d5535e8453f8b5f77959134760dac01ec5Puneet Lall private final CameraDirectionProvider mDirection; 160512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 161512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 162512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * The aspect ratio (width/height) of the full resolution for this camera. 163512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Usually the native aspect ratio of this camera. 164512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 1659cefdd495332719d987ffb942742ec602793d8d4Jiawen Chen private final float mFullSizeAspectRatio; 166512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** The Camera2 API capture session currently active. */ 167512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private CameraCaptureSession mCaptureSession; 168512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** The surface onto which to render the preview. */ 169512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private Surface mPreviewSurface; 170512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Whether closing of this device has been requested. */ 171512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private volatile boolean mIsClosed = false; 172512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 173512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Receives the normal captured images. */ 174512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private final ImageReader mCaptureImageReader; 175512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 176512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 177512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Maintains a buffer of images and their associated {@link CaptureResult}s. 178512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 179512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private ImageCaptureManager mCaptureManager; 180512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 181512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 182863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall * The sensor timestamps (which may not be relative to the system time) of 183863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall * the most recently captured images. 184512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 185863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall private final Set<Long> mCapturedImageTimestamps = Collections.synchronizedSet( 186863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall new HashSet<Long>()); 187512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 188512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Thread pool for performing slow jpeg encoding and saving tasks. */ 189512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private final ThreadPoolExecutor mImageSaverThreadPool; 190512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 191512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Pool of native byte buffers on which to store jpeg-encoded images. */ 1920ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall private final Pools.SynchronizedPool<ByteBuffer> mJpegByteBufferPool = 1930ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall new Pools.SynchronizedPool<ByteBuffer>(64); 194512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 195512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Current zoom value. 1.0 is no zoom. */ 196512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private float mZoomValue = 1f; 197512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Current crop region: set from mZoomValue. */ 198512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private Rect mCropRegion; 199512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** Current AE, AF, and AWB regions */ 200b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers private MeteringRectangle[] mAFRegions = ZERO_WEIGHT_3A_REGION; 201b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers private MeteringRectangle[] mAERegions = ZERO_WEIGHT_3A_REGION; 202512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 20317d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers private MediaActionSound mMediaActionSound = new MediaActionSound(); 20417d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers 205512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 206142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall * Ready state (typically displayed by the UI shutter-button) depends on two 207142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall * things:<br> 208182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * <ol> 209182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * <li>{@link #mCaptureManager} must be ready.</li> 210182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * <li>We must not be in the process of capturing a single, high-quality, 211182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * image.</li> 212182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * </ol> 213c2387dc7fa82fafb2dd2eac0e7280ff71dece0f4Puneet Lall * See {@link ListenerCombiner} and {@link #mReadyStateManager} for 214142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall * details of how this is managed. 215182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall */ 21668c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall private static enum ReadyStateRequirement { 2170ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall CAPTURE_MANAGER_READY, CAPTURE_NOT_IN_PROGRESS 21868c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall } 21968c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall 22068c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall /** 22168c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall * Handles the thread-safe logic of dispatching whenever the logical AND of 22268c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall * these constraints changes. 22368c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall */ 224c2387dc7fa82fafb2dd2eac0e7280ff71dece0f4Puneet Lall private final ListenerCombiner<ReadyStateRequirement> 225c2387dc7fa82fafb2dd2eac0e7280ff71dece0f4Puneet Lall mReadyStateManager = new ListenerCombiner<ReadyStateRequirement>( 226c2387dc7fa82fafb2dd2eac0e7280ff71dece0f4Puneet Lall ReadyStateRequirement.class, new ListenerCombiner.StateChangeListener() { 227142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall @Override 228c2387dc7fa82fafb2dd2eac0e7280ff71dece0f4Puneet Lall public void onStateChange(boolean state) { 229142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall broadcastReadyState(state); 230142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall } 231142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall }); 232182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall 233182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall /** 234580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * An {@link ImageCaptureListener} which will compress and save an image to 235580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * disk. 236580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 237580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private class ImageCaptureTask implements ImageCaptureListener { 238580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private final PhotoCaptureParameters mParams; 239580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private final CaptureSession mSession; 240580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 2410ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall public ImageCaptureTask(PhotoCaptureParameters parameters, CaptureSession session) { 242580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mParams = parameters; 243580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mSession = session; 244580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 245580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 246580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall @Override 2470ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall public void onImageCaptured(Image image, TotalCaptureResult captureResult) { 248580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall long timestamp = captureResult.get(CaptureResult.SENSOR_TIMESTAMP); 249580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 250863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // We should only capture the image if it hasn't been captured 251863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // before. Synchronization is necessary since 252863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // mCapturedImageTimestamps is read & modified elsewhere. 253863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall synchronized (mCapturedImageTimestamps) { 254863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall if (!mCapturedImageTimestamps.contains(timestamp)) { 255863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall mCapturedImageTimestamps.add(timestamp); 256580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 257580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // There was a more recent (or identical) image which has 258580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // begun being saved, so abort. 259580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return; 260580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 261863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall 262863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // Clear out old timestamps from the set. 263863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // We must keep old timestamps in the set a little longer (a 264863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // factor of 2 seems adequate) to ensure they are cleared out of 265863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // the ring buffer before their timestamp is removed from the 266863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // set. 267863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall long maxTimestamps = MAX_CAPTURE_IMAGES * 2; 268863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall if (mCapturedImageTimestamps.size() > maxTimestamps) { 269863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall ArrayList<Long> timestamps = new ArrayList<Long>(mCapturedImageTimestamps); 270863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall Collections.sort(timestamps); 271863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall for (int i = 0; i < timestamps.size() 272863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall && mCapturedImageTimestamps.size() > maxTimestamps; i++) { 273863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall mCapturedImageTimestamps.remove(timestamps.get(i)); 274863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall } 275863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall } 276580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 277580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 2780ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mReadyStateManager.setInput(ReadyStateRequirement.CAPTURE_NOT_IN_PROGRESS, true); 279182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall 280f6031c016d916db9789026dc0a6c559d8163a088Spike Sprague savePicture(image, mParams, mSession, captureResult); 281580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mParams.callback.onPictureTaken(mSession); 282580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Image saved. Frame number = " + captureResult.getFrameNumber()); 283580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 284580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 285580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 286580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 287512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Instantiates a new camera based on Camera 2 API. 288512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 289512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param device The underlying Camera 2 device. 290512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param characteristics The device's characteristics. 291512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param pictureSize the size of the final image to be taken. 292512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 293512001df0211fa8999593717a0f186457a5a9cefPuneet Lall OneCameraZslImpl(CameraDevice device, CameraCharacteristics characteristics, Size pictureSize) { 294580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Creating new OneCameraZslImpl"); 295580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 296512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mDevice = device; 297512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCharacteristics = characteristics; 298aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde mLensRange = LensRangeCalculator 299aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde .getDiopterToRatioCalculator(characteristics); 3009ceed0d5535e8453f8b5f77959134760dac01ec5Puneet Lall mDirection = new CameraDirectionProvider(mCharacteristics); 301512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mFullSizeAspectRatio = calculateFullSizeAspectRatio(characteristics); 302512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 303512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCameraThread = new HandlerThread("OneCamera2"); 304512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // If this thread stalls, it will delay viewfinder frames. 305512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCameraThread.setPriority(Thread.MAX_PRIORITY); 306512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCameraThread.start(); 307512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCameraHandler = new Handler(mCameraThread.getLooper()); 308512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 309580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCameraListenerThread = new HandlerThread("OneCamera2-Listener"); 310580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCameraListenerThread.start(); 311580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCameraListenerHandler = new Handler(mCameraListenerThread.getLooper()); 312512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 313512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // TODO: Encoding on multiple cores results in preview jank due to 314512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // excessive GC. 315512001df0211fa8999593717a0f186457a5a9cefPuneet Lall int numEncodingCores = CameraUtil.getNumCpuCores(); 316512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mImageSaverThreadPool = new ThreadPoolExecutor(numEncodingCores, numEncodingCores, 10, 317512001df0211fa8999593717a0f186457a5a9cefPuneet Lall TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); 318512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 3190ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCaptureManager = 3200ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall new ImageCaptureManager(MAX_CAPTURE_IMAGES, mCameraListenerHandler, 3210ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mImageSaverThreadPool); 322580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureManager.setCaptureReadyListener(new ImageCaptureManager.CaptureReadyListener() { 323512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 324512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void onReadyStateChange(boolean capturePossible) { 32568c25ac5373126670cb6c2324e40537bb47e72d9Puneet Lall mReadyStateManager.setInput(ReadyStateRequirement.CAPTURE_MANAGER_READY, 326182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall capturePossible); 327182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall } 328182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall }); 329182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall 330580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Listen for changes to auto focus state and dispatch to 331580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // mFocusStateListener. 332580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureManager.addMetadataChangeListener(CaptureResult.CONTROL_AF_STATE, 333580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall new ImageCaptureManager.MetadataChangeListener() { 334580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall @Override 335580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall public void onImageMetadataChange(Key<?> key, Object oldValue, Object newValue, 336580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureResult result) { 3370ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall FocusStateListener listener = mFocusStateListener; 3380ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall if (listener != null) { 3390ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall listener.onFocusStatusUpdate( 3400ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall AutoFocusHelper.stateFromCamera2State( 3414a748623618f2bae149c8cf385046666c717a7a9Andy Huibers result.get(CaptureResult.CONTROL_AF_STATE)), 342ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers result.getFrameNumber()); 3434a748623618f2bae149c8cf385046666c717a7a9Andy Huibers } 344580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 345580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall }); 346580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 347580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Allocate the image reader to store all images received from the 348580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // camera. 34980f44448e13b5d6d33f4aad63448d7b39b6dda0fPuneet Lall if (pictureSize == null) { 3504d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall // TODO The default should be selected by the caller, and 3514d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall // pictureSize should never be null. 3524d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall pictureSize = getDefaultPictureSize(); 35380f44448e13b5d6d33f4aad63448d7b39b6dda0fPuneet Lall } 354580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureImageReader = ImageReader.newInstance(pictureSize.getWidth(), 355580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall pictureSize.getHeight(), 356580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall sCaptureImageFormat, MAX_CAPTURE_IMAGES); 357512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 358512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCaptureImageReader.setOnImageAvailableListener(mCaptureManager, mCameraHandler); 35917d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers mMediaActionSound.load(MediaActionSound.SHUTTER_CLICK); 360512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 361512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 362987ee64612e2510004fdf08536746c87234d01c1Paul Rohde @Override 363987ee64612e2510004fdf08536746c87234d01c1Paul Rohde public void setFocusDistanceListener(FocusDistanceListener focusDistanceListener) { 364987ee64612e2510004fdf08536746c87234d01c1Paul Rohde if(mFocusDistanceListener == null) { 365987ee64612e2510004fdf08536746c87234d01c1Paul Rohde mCaptureManager.addMetadataChangeListener(CaptureResult.LENS_FOCUS_DISTANCE, 366987ee64612e2510004fdf08536746c87234d01c1Paul Rohde new ImageCaptureManager.MetadataChangeListener() { 367987ee64612e2510004fdf08536746c87234d01c1Paul Rohde @Override 368987ee64612e2510004fdf08536746c87234d01c1Paul Rohde public void onImageMetadataChange(Key<?> key, Object oldValue, 369987ee64612e2510004fdf08536746c87234d01c1Paul Rohde Object newValue, 370987ee64612e2510004fdf08536746c87234d01c1Paul Rohde CaptureResult result) { 371987ee64612e2510004fdf08536746c87234d01c1Paul Rohde Integer state = result.get(CaptureResult.LENS_STATE); 372aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde 373aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde // Forward changes if we have a new value and the camera 374aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde // A) Doesn't support lens state or B) lens state is 375aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde // reported and it is reported as moving. 376aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde if (newValue != null && 377aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde (state == null || state == CameraMetadata.LENS_STATE_MOVING)) { 378aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde mFocusDistanceListener.onFocusDistance((float) newValue, mLensRange); 379987ee64612e2510004fdf08536746c87234d01c1Paul Rohde } 380987ee64612e2510004fdf08536746c87234d01c1Paul Rohde } 381987ee64612e2510004fdf08536746c87234d01c1Paul Rohde }); 382987ee64612e2510004fdf08536746c87234d01c1Paul Rohde } 383987ee64612e2510004fdf08536746c87234d01c1Paul Rohde mFocusDistanceListener = focusDistanceListener; 384987ee64612e2510004fdf08536746c87234d01c1Paul Rohde } 385987ee64612e2510004fdf08536746c87234d01c1Paul Rohde 386512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 3874d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall * @return The largest supported picture size. 3884d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall */ 3894d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall public Size getDefaultPictureSize() { 3900ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall StreamConfigurationMap configs = 3910ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 3924d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall android.util.Size[] supportedSizes = configs.getOutputSizes(sCaptureImageFormat); 3934d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall 3944d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall // Find the largest supported size. 3954d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall android.util.Size largestSupportedSize = supportedSizes[0]; 3960ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall long largestSupportedSizePixels = 3970ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall largestSupportedSize.getWidth() * largestSupportedSize.getHeight(); 3984d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall for (int i = 0; i < supportedSizes.length; i++) { 3994d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall long numPixels = supportedSizes[i].getWidth() * supportedSizes[i].getHeight(); 4004d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall if (numPixels > largestSupportedSizePixels) { 4014d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall largestSupportedSize = supportedSizes[i]; 4024d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall largestSupportedSizePixels = numPixels; 4034d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall } 4044d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall } 4054d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall 4060ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall return new Size(largestSupportedSize.getWidth(), largestSupportedSize.getHeight()); 4074d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall } 4084d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall 40917d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers private void onShutterInvokeUI(final PhotoCaptureParameters params) { 41017d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers // Tell CaptureModule shutter has occurred so it can flash the screen. 41117d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers params.callback.onQuickExpose(); 41217d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers // Play shutter click sound. 41317d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK); 41417d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers } 41517d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers 4164d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall /** 417512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Take a picture. 418512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 419512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 420512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void takePicture(final PhotoCaptureParameters params, final CaptureSession session) { 4210ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mReadyStateManager.setInput(ReadyStateRequirement.CAPTURE_NOT_IN_PROGRESS, false); 422182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall 423512001df0211fa8999593717a0f186457a5a9cefPuneet Lall boolean useZSL = ZSL_ENABLED; 424512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 425580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // We will only capture images from the zsl ring-buffer which satisfy 426580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // this constraint. 4270ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall ArrayList<ImageCaptureManager.CapturedImageConstraint> zslConstraints = 4280ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall new ArrayList<ImageCaptureManager.CapturedImageConstraint>(); 429580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall zslConstraints.add(new ImageCaptureManager.CapturedImageConstraint() { 430580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall @Override 431580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall public boolean satisfiesConstraint(TotalCaptureResult captureResult) { 432580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Long timestamp = captureResult.get(CaptureResult.SENSOR_TIMESTAMP); 433580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Integer lensState = captureResult.get(CaptureResult.LENS_STATE); 434580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Integer flashState = captureResult.get(CaptureResult.FLASH_STATE); 435580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Integer flashMode = captureResult.get(CaptureResult.FLASH_MODE); 436580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Integer aeState = captureResult.get(CaptureResult.CONTROL_AE_STATE); 437580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE); 438580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Integer awbState = captureResult.get(CaptureResult.CONTROL_AWB_STATE); 439580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 440bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall if (lensState == null) { 441bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall lensState = CaptureResult.LENS_STATE_STATIONARY; 442bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall } 443bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall if (flashState == null) { 444bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall flashState = CaptureResult.FLASH_STATE_UNAVAILABLE; 445bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall } 446bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall if (flashMode == null) { 447bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall flashMode = CaptureResult.FLASH_MODE_OFF; 448bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall } 449bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall if (aeState == null) { 450bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall aeState = CaptureResult.CONTROL_AE_STATE_INACTIVE; 451bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall } 452bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall if (afState == null) { 453bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall afState = CaptureResult.CONTROL_AF_STATE_INACTIVE; 454bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall } 455bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall if (awbState == null) { 456bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall awbState = CaptureResult.CONTROL_AWB_STATE_INACTIVE; 457bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall } 458bbd6516a5aedf3173954ee0ece85a45ebb9d73aaPuneet Lall 459863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall synchronized (mCapturedImageTimestamps) { 460863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall if (mCapturedImageTimestamps.contains(timestamp)) { 461863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall // Don't save frames which we've already saved. 462863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall return false; 463863a5abf144db5c50c459d1c2f66543598aa26fcPuneet Lall } 464580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 465512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 466580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (lensState == CaptureResult.LENS_STATE_MOVING) { 467580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // If we know the lens was moving, don't use this image. 468580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 469580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 470512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 471580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (aeState == CaptureResult.CONTROL_AE_STATE_SEARCHING 472580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall || aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE) { 473580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 474580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 475512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 476580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (afState == CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN 477580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall || afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN) { 478580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 479580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 480512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 481580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (awbState == CaptureResult.CONTROL_AWB_STATE_SEARCHING) { 482580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 483512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 484512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 485580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return true; 486580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 487580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall }); 488580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // This constraint lets us capture images which have been explicitly 489580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // requested. See {@link RequestTag.EXPLICIT_CAPTURE}. 4900ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall ArrayList<ImageCaptureManager.CapturedImageConstraint> singleCaptureConstraint = 4910ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall new ArrayList<ImageCaptureManager.CapturedImageConstraint>(); 492580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall singleCaptureConstraint.add(new ImageCaptureManager.CapturedImageConstraint() { 493580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall @Override 494580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall public boolean satisfiesConstraint(TotalCaptureResult captureResult) { 495580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Object tag = captureResult.getRequest().getTag(); 496580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return tag == RequestTag.EXPLICIT_CAPTURE; 497580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 498580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall }); 499512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 500580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // If we can use ZSL, try to save a previously-captured frame, if an 501580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // acceptable one exists in the buffer. 502580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (useZSL) { 503580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall boolean capturedPreviousFrame = mCaptureManager.tryCaptureExistingImage( 504580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall new ImageCaptureTask(params, session), zslConstraints); 505512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (capturedPreviousFrame) { 506512001df0211fa8999593717a0f186457a5a9cefPuneet Lall Log.v(TAG, "Saving previous frame"); 50717d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers onShutterInvokeUI(params); 508512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } else { 509580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "No good image Available. Capturing next available good image."); 510512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // If there was no good frame available in the ring buffer 511512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // already, capture the next good image. 512580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // TODO Disable the shutter button until this image is captured. 513580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 514386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall Flash flashMode = Flash.OFF; 515386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall 516386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall if (flashMode == Flash.ON || flashMode == Flash.AUTO) { 517580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // We must issue a request for a single capture using the 518580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // flash, including an AE precapture trigger. 519580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 520580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // The following sets up a sequence of events which will 521580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // occur in reverse order to the associated method 522580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // calls: 523580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // 1. Send a request to trigger the Auto Exposure Precapture 524580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // 2. Wait for the AE_STATE to leave the PRECAPTURE state, 525580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // and then send a request for a single image, with the 526580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // appropriate flash settings. 527580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // 3. Capture the next appropriate image, which should be 528580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // the one we requested in (2). 529580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 530580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureManager.captureNextImage(new ImageCaptureTask(params, session), 531580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall singleCaptureConstraint); 532580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 533580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureManager.addMetadataChangeListener(CaptureResult.CONTROL_AE_STATE, 534580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall new MetadataChangeListener() { 535580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall @Override 536580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall public void onImageMetadataChange(Key<?> key, Object oldValue, 5370ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall Object newValue, 5380ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall CaptureResult result) { 539580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "AE State Changed"); 5400ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall if (oldValue.equals(Integer.valueOf( 5410ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall CaptureResult.CONTROL_AE_STATE_PRECAPTURE))) { 542580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureManager.removeMetadataChangeListener(key, this); 543580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall sendSingleRequest(params); 5440ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall // TODO: Delay this until 5450ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall // onCaptureStarted(). 54617d9084e38e64f06a9d411d64fe3c2739d299cdaAndy Huibers onShutterInvokeUI(params); 547580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 548580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 549580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall }); 550580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 551386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall sendAutoExposureTriggerRequest(flashMode); 552580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 553580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // We may get here if, for example, the auto focus is in the 554580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // middle of a scan. 555580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // If the flash is off, we should just wait for the next 556580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // image that arrives. This will have minimal delay since we 557580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // do not need to send a new capture request. 558580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureManager.captureNextImage(new ImageCaptureTask(params, session), 559580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall zslConstraints); 560580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 561512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 562580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 563580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // TODO If we can't save a previous frame, create a new capture 564580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // request to do what we need (e.g. flash) and call 565580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // captureNextImage(). 566580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall throw new UnsupportedOperationException("Non-ZSL capture not yet supported"); 567512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 568512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 569512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 570512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 571512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void startPreview(Surface previewSurface, CaptureReadyCallback listener) { 572512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mPreviewSurface = previewSurface; 573512001df0211fa8999593717a0f186457a5a9cefPuneet Lall setupAsync(mPreviewSurface, listener); 574512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 575512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 576512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 577c7251753978f80dc40131e7676f69f7e86208fd1Puneet Lall public void close() { 578512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (mIsClosed) { 579512001df0211fa8999593717a0f186457a5a9cefPuneet Lall Log.w(TAG, "Camera is already closed."); 580512001df0211fa8999593717a0f186457a5a9cefPuneet Lall return; 581512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 582512001df0211fa8999593717a0f186457a5a9cefPuneet Lall try { 5839cd94d77bcafad38f15b318ea5c9dbc0849c1ecdPuneet Lall mCaptureSession.stopRepeating(); 584512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } catch (CameraAccessException e) { 585512001df0211fa8999593717a0f186457a5a9cefPuneet Lall Log.e(TAG, "Could not abort captures in progress."); 586512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 587512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mIsClosed = true; 588512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCameraThread.quitSafely(); 589512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mDevice.close(); 590512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCaptureManager.close(); 5919cd94d77bcafad38f15b318ea5c9dbc0849c1ecdPuneet Lall mCaptureImageReader.close(); 592512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 593512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 594c6da1a12fe8b78e2fbebe1af5efee514bc8e25eeSascha Haeberling public Size[] getSupportedPreviewSizes() { 5950ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall StreamConfigurationMap config = 5960ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 597512001df0211fa8999593717a0f186457a5a9cefPuneet Lall return Size.convert(config.getOutputSizes(sCaptureImageFormat)); 598512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 599512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 6009cefdd495332719d987ffb942742ec602793d8d4Jiawen Chen public float getFullSizeAspectRatio() { 601512001df0211fa8999593717a0f186457a5a9cefPuneet Lall return mFullSizeAspectRatio; 602512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 603512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 604f6031c016d916db9789026dc0a6c559d8163a088Spike Sprague @Override 6059ceed0d5535e8453f8b5f77959134760dac01ec5Puneet Lall public Facing getDirection() { 6069ceed0d5535e8453f8b5f77959134760dac01ec5Puneet Lall return mDirection.getDirection(); 6079ceed0d5535e8453f8b5f77959134760dac01ec5Puneet Lall } 608512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 609512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 610512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private void savePicture(Image image, final PhotoCaptureParameters captureParams, 611f6031c016d916db9789026dc0a6c559d8163a088Spike Sprague CaptureSession session, CaptureResult result) { 612512001df0211fa8999593717a0f186457a5a9cefPuneet Lall int heading = captureParams.heading; 6130bdc4b54a18c18d7094b2e4cea1e238005c5c4a2Senpo Hu int degrees = CameraUtil.getJpegRotation(captureParams.orientation, mCharacteristics); 614512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 615f6031c016d916db9789026dc0a6c559d8163a088Spike Sprague ExifInterface exif = new ExifInterface(); 616512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // TODO: Add more exif tags here. 617512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 6180ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall Size size = getImageSizeForOrientation(image.getWidth(), image.getHeight(), 6190ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall degrees); 620512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 6210ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall exif.setTag(exif.buildTag(ExifInterface.TAG_PIXEL_X_DIMENSION, size.getWidth())); 6220ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall exif.setTag(exif.buildTag(ExifInterface.TAG_PIXEL_Y_DIMENSION, size.getHeight())); 6230ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall 6240ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall exif.setTag( 6250ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall exif.buildTag(ExifInterface.TAG_ORIENTATION, ExifInterface.Orientation.TOP_LEFT)); 626512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 627512001df0211fa8999593717a0f186457a5a9cefPuneet Lall // Set GPS heading direction based on sensor, if location is on. 628512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (heading >= 0) { 6290ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall ExifTag directionRefTag = exif.buildTag(ExifInterface.TAG_GPS_IMG_DIRECTION_REF, 630512001df0211fa8999593717a0f186457a5a9cefPuneet Lall ExifInterface.GpsTrackRef.MAGNETIC_DIRECTION); 6310ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall ExifTag directionTag = 6320ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall exif.buildTag(ExifInterface.TAG_GPS_IMG_DIRECTION, new Rational(heading, 1)); 633512001df0211fa8999593717a0f186457a5a9cefPuneet Lall exif.setTag(directionRefTag); 634512001df0211fa8999593717a0f186457a5a9cefPuneet Lall exif.setTag(directionTag); 635512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 636f6031c016d916db9789026dc0a6c559d8163a088Spike Sprague new ExifUtil(exif).populateExif(Optional.<TaskImageContainer.TaskImage>absent(), 6375ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lall Optional.of((CaptureResultProxy) new AndroidCaptureResultProxy(result)), 6385ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lall Optional.<Location>absent()); 63937036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling ListenableFuture<Optional<Uri>> futureUri = session.saveAndFinish( 64037036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling acquireJpegBytes(image, degrees), 64137036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling size.getWidth(), size.getHeight(), 0, exif); 64237036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling Futures.addCallback(futureUri, new FutureCallback<Optional<Uri>>() { 64337036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling @Override 64437036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling public void onSuccess(Optional<Uri> uriOptional) { 64537036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling captureParams.callback.onPictureSaved(uriOptional.orNull()); 64637036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling } 64737036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling 64837036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling @Override 64937036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling public void onFailure(Throwable throwable) { 65037036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling captureParams.callback.onPictureSaved(null); 65137036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling } 65237036186326fb68c27063f97305405d3667a5eb3Sascha Haeberling }); 653512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 654512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 655512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 656512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Asynchronously sets up the capture session. 657512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 658512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param previewSurface the surface onto which the preview should be 659512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * rendered. 660512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param listener called when setup is completed. 661512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 662512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private void setupAsync(final Surface previewSurface, final CaptureReadyCallback listener) { 663512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCameraHandler.post(new Runnable() { 664512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 665512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void run() { 666512001df0211fa8999593717a0f186457a5a9cefPuneet Lall setup(previewSurface, listener); 667512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 668512001df0211fa8999593717a0f186457a5a9cefPuneet Lall }); 669512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 670512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 671512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 672512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Configures and attempts to create a capture session. 673512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 674512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param previewSurface the surface onto which the preview should be 675512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * rendered. 676512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param listener called when the setup is completed. 677512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 678512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private void setup(Surface previewSurface, final CaptureReadyCallback listener) { 679512001df0211fa8999593717a0f186457a5a9cefPuneet Lall try { 680512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (mCaptureSession != null) { 681512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCaptureSession.abortCaptures(); 682512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCaptureSession = null; 683512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 684512001df0211fa8999593717a0f186457a5a9cefPuneet Lall List<Surface> outputSurfaces = new ArrayList<Surface>(2); 685512001df0211fa8999593717a0f186457a5a9cefPuneet Lall outputSurfaces.add(previewSurface); 686512001df0211fa8999593717a0f186457a5a9cefPuneet Lall outputSurfaces.add(mCaptureImageReader.getSurface()); 687512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 688f5c62537715e8ab5e586491b75e8ddff9a3d9f6aAlan Newberger mDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() { 689512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 690512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void onConfigureFailed(CameraCaptureSession session) { 691512001df0211fa8999593717a0f186457a5a9cefPuneet Lall listener.onSetupFailed(); 692512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 693512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 694512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 695512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void onConfigured(CameraCaptureSession session) { 696512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCaptureSession = session; 697b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers mAFRegions = ZERO_WEIGHT_3A_REGION; 698b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers mAERegions = ZERO_WEIGHT_3A_REGION; 699580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mZoomValue = 1f; 700580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCropRegion = cropRegionForZoom(mZoomValue); 701580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall boolean success = sendRepeatingCaptureRequest(); 702580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (success) { 703142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall mReadyStateManager.setInput(ReadyStateRequirement.CAPTURE_NOT_IN_PROGRESS, 704142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall true); 705142b5bf5e10db858c2d2e69fd93d6565ba51363bPuneet Lall mReadyStateManager.notifyListeners(); 706580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall listener.onReadyForCapture(); 707580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 708580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall listener.onSetupFailed(); 709580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 710512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 711512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 712512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 713512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void onClosed(CameraCaptureSession session) { 714512001df0211fa8999593717a0f186457a5a9cefPuneet Lall super.onClosed(session); 715512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 716512001df0211fa8999593717a0f186457a5a9cefPuneet Lall }, mCameraHandler); 717512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } catch (CameraAccessException ex) { 718512001df0211fa8999593717a0f186457a5a9cefPuneet Lall Log.e(TAG, "Could not set up capture session", ex); 719512001df0211fa8999593717a0f186457a5a9cefPuneet Lall listener.onSetupFailed(); 720512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 721512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 722512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 723580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private void addRegionsToCaptureRequestBuilder(CaptureRequest.Builder builder) { 724b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers builder.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions); 725b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers builder.set(CaptureRequest.CONTROL_AF_REGIONS, mAFRegions); 726580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion); 727580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 728580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 729580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private void addFlashToCaptureRequestBuilder(CaptureRequest.Builder builder, Flash flashMode) { 730580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall switch (flashMode) { 731580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall case ON: 732580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AE_MODE, 733580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH); 734580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE); 735580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall break; 736580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall case OFF: 7370ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); 738580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); 739580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall break; 740580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall case AUTO: 741580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AE_MODE, 742580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); 743580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall break; 744580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 745580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 746580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 747512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 748580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * Request a stream of images. 749512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 750580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * @return true if successful, false if there was an error submitting the 751580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * capture request. 752512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 753580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private boolean sendRepeatingCaptureRequest() { 754580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "sendRepeatingCaptureRequest()"); 755512001df0211fa8999593717a0f186457a5a9cefPuneet Lall try { 756580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.Builder builder; 757580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 7580ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); 759580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 760580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 761580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 762512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 763512001df0211fa8999593717a0f186457a5a9cefPuneet Lall builder.addTarget(mPreviewSurface); 764512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 765580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 766580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mCaptureImageReader.getSurface()); 767580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 768580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 769580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); 770512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 771512001df0211fa8999593717a0f186457a5a9cefPuneet Lall builder.set(CaptureRequest.CONTROL_AF_MODE, 772580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 773580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); 774512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 775580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); 776580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); 777512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 778580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall addRegionsToCaptureRequestBuilder(builder); 779512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 7800ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCaptureSession.setRepeatingRequest(builder.build(), mCaptureManager, mCameraHandler); 781580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return true; 782580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } catch (CameraAccessException e) { 783580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 784580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Could not execute zero-shutter-lag repeating request.", e); 785580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 786580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Could not execute preview request.", e); 787512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 788580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 789580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 790580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 791580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 792580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 793580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * Request a single image. 794580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * 795580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * @return true if successful, false if there was an error submitting the 796580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * capture request. 797580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 798580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private boolean sendSingleRequest(OneCamera.PhotoCaptureParameters params) { 799580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "sendSingleRequest()"); 800580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall try { 801580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.Builder builder; 802580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 803580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 804580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mPreviewSurface); 805580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 806580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Always add this surface for single image capture requests. 807580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mCaptureImageReader.getSurface()); 808580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 809580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); 810580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 811386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall Flash flashMode = Flash.OFF; 812386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall addFlashToCaptureRequestBuilder(builder, flashMode); 813580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall addRegionsToCaptureRequestBuilder(builder); 814580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 815580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); 816580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); 817580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 818580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Tag this as a special request which should be saved. 819580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.setTag(RequestTag.EXPLICIT_CAPTURE); 820580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 821580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (sCaptureImageFormat == ImageFormat.JPEG) { 822580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.JPEG_QUALITY, (byte) (JPEG_QUALITY)); 823580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.JPEG_ORIENTATION, 824580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CameraUtil.getJpegRotation(params.orientation, mCharacteristics)); 825580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 826580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 8270ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCaptureSession.capture(builder.build(), mCaptureManager, mCameraHandler); 828580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return true; 829580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } catch (CameraAccessException e) { 830580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Could not execute single still capture request.", e); 831580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 832580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 833580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 834580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 8351321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang private boolean sendRepeatingBurstCaptureRequest() { 8361321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang Log.v(TAG, "sendRepeatingBurstCaptureRequest()"); 8371321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang try { 8381321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang CaptureRequest.Builder builder; 8391321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_VIDEO_SNAPSHOT); 8401321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.addTarget(mPreviewSurface); 8411321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang 8421321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang if (ZSL_ENABLED) { 8431321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.addTarget(mCaptureImageReader.getSurface()); 8441321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang } 8451321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang 8461321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); 8471321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.set(CaptureRequest.CONTROL_AF_MODE, 8481321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO); 8491321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); 8501321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang 8511321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); 8521321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF); 8531321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang 8541321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang addRegionsToCaptureRequestBuilder(builder); 8551321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang 8561321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang mCaptureSession.setRepeatingRequest(builder.build(), mCaptureManager, mCameraHandler); 8571321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang return true; 8581321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang } catch (CameraAccessException e) { 8591321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang Log.v(TAG, "Could not send repeating burst capture request.", e); 8601321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang return false; 8611321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang } 8621321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang } 8631321823277e30b0be46f4911418b7b64cfc7d1c0Radford Juang 864580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private boolean sendAutoExposureTriggerRequest(Flash flashMode) { 865580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "sendAutoExposureTriggerRequest()"); 866580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall try { 867580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.Builder builder; 868580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 8690ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); 870580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 871580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 872580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 873580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 874580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mPreviewSurface); 875580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 876580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 877580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mCaptureImageReader.getSurface()); 878580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 879580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 880580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); 881580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 882580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, 883580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START); 884580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 885580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall addRegionsToCaptureRequestBuilder(builder); 886580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall addFlashToCaptureRequestBuilder(builder, flashMode); 887580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 8880ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCaptureSession.capture(builder.build(), mCaptureManager, mCameraHandler); 889580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 890580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return true; 891580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } catch (CameraAccessException e) { 892580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Could not execute auto exposure trigger request.", e); 893580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 894580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 895580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 896580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 897580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 898580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 899580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private boolean sendAutoFocusTriggerRequest() { 900580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "sendAutoFocusTriggerRequest()"); 901580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall try { 902580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.Builder builder; 903580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 9040ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); 905580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 906580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 907512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 908580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 909580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mPreviewSurface); 910580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 911580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 912580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mCaptureImageReader.getSurface()); 913580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 914580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 915580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO); 916580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 917580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall addRegionsToCaptureRequestBuilder(builder); 918580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 919580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO); 920580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); 921580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 9220ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall mCaptureSession.capture(builder.build(), mCaptureManager, mCameraHandler); 923580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 924580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return true; 925580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } catch (CameraAccessException e) { 926580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Could not execute auto focus trigger request.", e); 927580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 928580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 929580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 930580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 931580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall /** 932580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * Like {@link #sendRepeatingCaptureRequest()}, but with the focus held 933580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * constant. 934580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * 935580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * @return true if successful, false if there was an error submitting the 936580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall * capture request. 937580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall */ 938580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private boolean sendAutoFocusHoldRequest() { 939580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "sendAutoFocusHoldRequest()"); 940580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall try { 941580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall CaptureRequest.Builder builder; 942580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 9430ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); 944580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } else { 945580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder = mDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 946580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 947580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 948580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mPreviewSurface); 949580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 950580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall if (ZSL_ENABLED) { 951580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.addTarget(mCaptureImageReader.getSurface()); 952580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 953580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 954580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); 955580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 956580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MODE_AUTO); 957580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall builder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_IDLE); 958580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 959580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall addRegionsToCaptureRequestBuilder(builder); 960580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // TODO: This should fire the torch, if appropriate. 961580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 962580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCaptureSession.setRepeatingRequest(builder.build(), mCaptureManager, mCameraHandler); 963580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 964580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return true; 965580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } catch (CameraAccessException e) { 966580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall Log.v(TAG, "Could not execute auto focus hold request.", e); 967580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall return false; 968512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 969512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 970512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 971512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 972512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Calculate the aspect ratio of the full size capture on this device. 973512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 974512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @param characteristics the characteristics of the camera device. 975512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @return The aspect ration, in terms of width/height of the full capture 976512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * size. 977512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 9789cefdd495332719d987ffb942742ec602793d8d4Jiawen Chen private static float calculateFullSizeAspectRatio(CameraCharacteristics characteristics) { 979512001df0211fa8999593717a0f186457a5a9cefPuneet Lall Rect activeArraySize = 980512001df0211fa8999593717a0f186457a5a9cefPuneet Lall characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); 9819cefdd495332719d987ffb942742ec602793d8d4Jiawen Chen return ((float) activeArraySize.width()) / activeArraySize.height(); 982512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 983512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 984512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 9850ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * @param originalWidth the width of the original image captured from the 9860ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * camera 9870ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * @param originalHeight the height of the original image captured from the 9880ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * camera 9890ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * @param orientation the rotation to apply, in degrees. 9900ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * @return The size of the final rotated image 9910ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall */ 9920ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall private Size getImageSizeForOrientation(int originalWidth, int originalHeight, 9930ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall int orientation) { 9940ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall if (orientation == 0 || orientation == 180) { 9950ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall return new Size(originalWidth, originalHeight); 9960ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall } else if (orientation == 90 || orientation == 270) { 9970ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall return new Size(originalHeight, originalWidth); 9980ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall } else { 9990ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall throw new InvalidParameterException("Orientation not supported."); 10000ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall } 10010ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall } 10020ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall 10030ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall /** 1004512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * Given an image reader, extracts the JPEG image bytes and then closes the 1005512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * reader. 1006512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * 1007182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * @param img the image from which to extract jpeg bytes or compress to 1008182ba6f13e9dab9a9c0341efe4c907ff7853352dPuneet Lall * jpeg. 10090bdc4b54a18c18d7094b2e4cea1e238005c5c4a2Senpo Hu * @param degrees the angle to rotate the image clockwise, in degrees. Rotation is 10100ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall * only applied to YUV images. 1011512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @return The bytes of the JPEG image. Newly allocated. 1012512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 10130ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall private byte[] acquireJpegBytes(Image img, int degrees) { 1014512001df0211fa8999593717a0f186457a5a9cefPuneet Lall ByteBuffer buffer; 1015512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1016512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (img.getFormat() == ImageFormat.JPEG) { 1017512001df0211fa8999593717a0f186457a5a9cefPuneet Lall Image.Plane plane0 = img.getPlanes()[0]; 1018512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer = plane0.getBuffer(); 1019512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1020512001df0211fa8999593717a0f186457a5a9cefPuneet Lall byte[] imageBytes = new byte[buffer.remaining()]; 1021512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer.get(imageBytes); 1022512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer.rewind(); 1023512001df0211fa8999593717a0f186457a5a9cefPuneet Lall return imageBytes; 1024512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } else if (img.getFormat() == ImageFormat.YUV_420_888) { 1025512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer = mJpegByteBufferPool.acquire(); 1026512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (buffer == null) { 1027512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer = ByteBuffer.allocateDirect(img.getWidth() * img.getHeight() * 3); 1028512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1029512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 103030ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin int numBytes = JpegUtilNative.compressJpegFromYUV420Image( 103130ccdac56450e5b1927e14a6eede2b86a30c42ebI-Jong Lin new AndroidImageProxy(img), buffer, JPEG_QUALITY, 10320ad7ab0b0a0d17a96438a503d0c918979b5d6480Puneet Lall degrees); 1033512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1034512001df0211fa8999593717a0f186457a5a9cefPuneet Lall if (numBytes < 0) { 1035512001df0211fa8999593717a0f186457a5a9cefPuneet Lall throw new RuntimeException("Error compressing jpeg."); 1036512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1037512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1038512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer.limit(numBytes); 1039512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1040512001df0211fa8999593717a0f186457a5a9cefPuneet Lall byte[] imageBytes = new byte[buffer.remaining()]; 1041512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer.get(imageBytes); 1042512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1043512001df0211fa8999593717a0f186457a5a9cefPuneet Lall buffer.clear(); 1044512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mJpegByteBufferPool.release(buffer); 1045512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1046512001df0211fa8999593717a0f186457a5a9cefPuneet Lall return imageBytes; 1047512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } else { 1048512001df0211fa8999593717a0f186457a5a9cefPuneet Lall throw new RuntimeException("Unsupported image format."); 1049512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1050512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1051512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1052580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall private void startAFCycle() { 1053580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Clean up any existing AF cycle's pending callbacks. 1054580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCameraHandler.removeCallbacksAndMessages(FOCUS_RESUME_CALLBACK_TOKEN); 1055580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 1056580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Send a single CONTROL_AF_TRIGGER_START capture request. 1057580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall sendAutoFocusTriggerRequest(); 1058580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 1059580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // Immediately send a request for a regular preview stream, but with 1060580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // CONTROL_AF_MODE_AUTO set so that the focus remains constant after the 1061580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall // AF cycle completes. 1062580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall sendAutoFocusHoldRequest(); 1063580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall 1064b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers // Waits Settings3A.getFocusHoldMillis() milliseconds before sending 1065b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers // a request for a regular preview stream to resume. 1066580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall mCameraHandler.postAtTime(new Runnable() { 106780f44448e13b5d6d33f4aad63448d7b39b6dda0fPuneet Lall @Override 1068580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall public void run() { 1069b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers mAERegions = ZERO_WEIGHT_3A_REGION; 1070b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers mAFRegions = ZERO_WEIGHT_3A_REGION; 1071580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall sendRepeatingCaptureRequest(); 1072580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall } 1073b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers }, FOCUS_RESUME_CALLBACK_TOKEN, 1074b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers SystemClock.uptimeMillis() + Settings3A.getFocusHoldMillis()); 1075512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1076512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1077512001df0211fa8999593717a0f186457a5a9cefPuneet Lall /** 1078512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * @see com.android.camera.one.OneCamera#triggerFocusAndMeterAtPoint(float, 1079512001df0211fa8999593717a0f186457a5a9cefPuneet Lall * float) 1080512001df0211fa8999593717a0f186457a5a9cefPuneet Lall */ 1081512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 1082512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void triggerFocusAndMeterAtPoint(float nx, float ny) { 10830971376b0ddf12c8aa886ad9109f6a8929095154Jiawen Chen int sensorOrientation = mCharacteristics.get( 10840971376b0ddf12c8aa886ad9109f6a8929095154Jiawen Chen CameraCharacteristics.SENSOR_ORIENTATION); 10850971376b0ddf12c8aa886ad9109f6a8929095154Jiawen Chen mAERegions = AutoFocusHelper.aeRegionsForNormalizedCoord(nx, ny, mCropRegion, sensorOrientation); 10860971376b0ddf12c8aa886ad9109f6a8929095154Jiawen Chen mAFRegions = AutoFocusHelper.afRegionsForNormalizedCoord(nx, ny, mCropRegion, sensorOrientation); 1087512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1088580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall startAFCycle(); 1089512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1090512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1091512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 1092512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public Size pickPreviewSize(Size pictureSize, Context context) { 10934d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall if (pictureSize == null) { 10944d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall // TODO The default should be selected by the caller, and 10954d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall // pictureSize should never be null. 10964d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall pictureSize = getDefaultPictureSize(); 10974d6d676c368b70e8c0fcf462e51de1d59fe34028Puneet Lall } 1098512001df0211fa8999593717a0f186457a5a9cefPuneet Lall float pictureAspectRatio = pictureSize.getWidth() / (float) pictureSize.getHeight(); 10996ba8eeea4758e29318c615e978c63599c30438b4Paul Rohde return CaptureModuleUtil.getOptimalPreviewSize(getSupportedPreviewSizes(), 11006ba8eeea4758e29318c615e978c63599c30438b4Paul Rohde pictureAspectRatio); 1101512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1102512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1103512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 1104512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public float getMaxZoom() { 1105512001df0211fa8999593717a0f186457a5a9cefPuneet Lall return mCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM); 1106512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1107512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1108512001df0211fa8999593717a0f186457a5a9cefPuneet Lall @Override 1109512001df0211fa8999593717a0f186457a5a9cefPuneet Lall public void setZoom(float zoom) { 1110512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mZoomValue = zoom; 1111512001df0211fa8999593717a0f186457a5a9cefPuneet Lall mCropRegion = cropRegionForZoom(zoom); 1112580f451fc85cc752e71eb730006b90d09aaafb55Puneet Lall sendRepeatingCaptureRequest(); 1113512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1114512001df0211fa8999593717a0f186457a5a9cefPuneet Lall 1115512001df0211fa8999593717a0f186457a5a9cefPuneet Lall private Rect cropRegionForZoom(float zoom) { 1116b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers return AutoFocusHelper.cropRegionForZoom(mCharacteristics, zoom); 1117512001df0211fa8999593717a0f186457a5a9cefPuneet Lall } 1118512001df0211fa8999593717a0f186457a5a9cefPuneet Lall} 1119