1fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford/* 2fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Copyright (C) 2015 The Android Open Source Project 3fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 4fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Licensed under the Apache License, Version 2.0 (the "License"); 5fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * you may not use this file except in compliance with the License. 6fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * You may obtain a copy of the License at 7fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 8fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * http://www.apache.org/licenses/LICENSE-2.0 9fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 10fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Unless required by applicable law or agreed to in writing, software 11fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * distributed under the License is distributed on an "AS IS" BASIS, 12fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * See the License for the specific language governing permissions and 14fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * limitations under the License. 15fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 16fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 17fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordpackage com.android.example.rscamera; 18fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 19fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.content.ContentResolver; 20fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.graphics.ImageFormat; 21fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.CameraAccessException; 22fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.CameraCaptureSession; 23fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.CameraCharacteristics; 24fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.CameraDevice; 25fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.CameraManager; 26fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.CaptureRequest; 27fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.TotalCaptureResult; 28fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.hardware.camera2.params.StreamConfigurationMap; 29fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.media.Image; 30fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.media.ImageReader; 31fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.os.ConditionVariable; 32fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.os.Handler; 33fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.os.HandlerThread; 34fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.os.Looper; 35fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.util.Log; 36fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.util.Range; 37fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.util.Size; 38fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.view.Surface; 39fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.view.SurfaceHolder; 40fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.widget.Toast; 41fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 42fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport com.android.example.rscamera.rscamera.R; 43fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 44fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.File; 45fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.FileNotFoundException; 46fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.FileOutputStream; 47fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.IOException; 48fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.OutputStream; 49fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.nio.ByteBuffer; 50fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.util.ArrayList; 51fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.util.Arrays; 52fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.util.Collections; 53fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.util.Comparator; 54fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.util.List; 55fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 56fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford/** 57fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Simple interface for operating the camera, with major camera operations 58fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * all performed on a background handler thread. 59fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 60fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordpublic class CameraOps { 61fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 62fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private static final String TAG = "CameraOps"; 63fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private static final long ONE_SECOND = 1000000000; 64fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public static final long CAMERA_CLOSE_TIMEOUT = 2000; // ms 65fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 66fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final CameraManager mCameraManager; 67fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private CameraDevice mCameraDevice; 68fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private CameraCaptureSession mCameraSession; 69fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private List<Surface> mSurfaces; 70fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 71fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final ConditionVariable mCloseWaiter = new ConditionVariable(); 72fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 73fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private HandlerThread mCameraThread; 74fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private Handler mCameraHandler; 75fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 76fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final ErrorDisplayer mErrorDisplayer; 77fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 78fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final CameraReadyListener mReadyListener; 79fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final Handler mReadyHandler; 80fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 81fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private int mISOmax; 82fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private int mISOmin; 83fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private long mExpMax; 84fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private long mExpMin; 85fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private float mFocusMin; 86fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private float mFocusDist = 0; 87fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private int mIso; 88fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean mAutoExposure = true; 89fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean mAutoFocus = true; 90fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private long mExposure = ONE_SECOND / 33; 91fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 92fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private Object mAutoExposureTag = new Object(); 93fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 94fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private ImageReader mImageReader; 95fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private Handler mBackgroundHandler; 96fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private CameraCharacteristics mCameraInfo; 97fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private HandlerThread mBackgroundThread; 98fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CaptureRequest.Builder mHdrBuilder; 99fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private Surface mProcessingNormalSurface; 100fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CaptureRequest mPreviewRequest; 101fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private String mSaveFileName; 102fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private ContentResolver mContentResolver; 103fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 104fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public String resume() { 105fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = "Unknown error"; 106fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean foundCamera = false; 107fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 108fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Find first back-facing camera that has necessary capability 109fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String[] cameraIds = mCameraManager.getCameraIdList(); 110fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford for (String id : cameraIds) { 111fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraCharacteristics info = mCameraManager.getCameraCharacteristics(id); 112fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int facing = info.get(CameraCharacteristics.LENS_FACING); 113fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 114fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int level = info.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL); 115fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean hasFullLevel 116fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford = (level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL); 117fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 118fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int[] capabilities = info.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); 119fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int syncLatency = info.get(CameraCharacteristics.SYNC_MAX_LATENCY); 120fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean hasManualControl = hasCapability(capabilities, 121fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR); 122fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean hasEnoughCapability = hasManualControl && 123fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford syncLatency == CameraCharacteristics.SYNC_MAX_LATENCY_PER_FRAME_CONTROL; 124fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Range<Integer> irange; 125fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Range<Long> lrange; 126fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 127fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford irange = info.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE); 128fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mISOmax = irange.getUpper(); 129fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mISOmin = irange.getLower(); 130fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford lrange = info.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); 131fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mExpMax = lrange.getUpper(); 132fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mExpMin = lrange.getLower(); 133fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mFocusMin = info.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE); 134fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 135fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mFocusDist = mFocusMin; 136fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford StreamConfigurationMap map = info.get( 137fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 138fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Size[] sizes = map.getOutputSizes(ImageFormat.JPEG); 139fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Size largest = Collections.max(Arrays.asList(sizes), new Comparator<Size>() { 140fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 141fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public int compare(Size lhs, Size rhs) { 142fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int leftArea = lhs.getHeight() * lhs.getWidth(); 143fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int rightArea = lhs.getHeight() * lhs.getWidth(); 144fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return Integer.compare(leftArea, rightArea); 145fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 146fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 147fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), 148fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ImageFormat.JPEG, /*maxImages*/2); 149fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mImageReader.setOnImageAvailableListener( 150fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mOnImageAvailableListener, mBackgroundHandler); 151fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 152fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (facing == CameraCharacteristics.LENS_FACING_BACK && 153fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford (hasFullLevel || hasEnoughCapability)) { 154fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Found suitable camera - get info, open, and set up outputs 155fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraInfo = info; 156fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford openCamera(id); 157fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford foundCamera = true; 158fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford break; 159fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 160fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 161fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (!foundCamera) { 162fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford errorMessage = "no back camera"; 163fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 164fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 165fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford errorMessage = e.getMessage(); 166fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 167fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // startBackgroundThread 168fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundThread = new HandlerThread("CameraBackground"); 169fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundThread.start(); 170fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); 171fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return (foundCamera) ? null : errorMessage; 172fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 173fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 174fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 175fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private boolean hasCapability(int[] capabilities, int capability) { 176fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford for (int c : capabilities) { 177fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (c == capability) return true; 178fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 179fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return false; 180fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 181fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 182fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final ImageReader.OnImageAvailableListener mOnImageAvailableListener 183fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford = new ImageReader.OnImageAvailableListener() { 184fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 185fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 186fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onImageAvailable(ImageReader reader) { 187fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mSaveFileName, mContentResolver)); 188fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 189fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 190fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 191fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 192fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 193fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Saves a JPEG {@link android.media.Image} into the specified {@link java.io.File}. 194fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 195fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private static class ImageSaver implements Runnable { 196fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final Image mImage; 197fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private final String mName; 198fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ContentResolver mContentResolver; 199fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 200fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public ImageSaver(Image image, String fileName, ContentResolver contentResolver) { 201fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mImage = image; 202fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mName = fileName; 203fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mContentResolver = contentResolver; 204fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 205fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 206fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 207fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 208fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Log.v(TAG, "SAVING..."); 209fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford MediaStoreSaver.insertImage(mContentResolver, new MediaStoreSaver.StreamWriter() { 210fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 211fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void write(OutputStream imageOut) throws IOException { 212fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 213fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ByteBuffer buffer = mImage.getPlanes()[0].getBuffer(); 214fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford byte[] bytes = new byte[buffer.remaining()]; 215fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford buffer.get(bytes); 216fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford imageOut.write(bytes); 217fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } finally { 218fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mImage.close(); 219fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 220fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 221fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }, mName, "Saved from Simple Camera Demo"); 222fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 223fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 224fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 225fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 226fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Create a new camera ops thread. 227fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 228fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * @param errorDisplayer listener for displaying error messages 229fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * @param readyListener listener for notifying when camera is ready for requests 230fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 231fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraOps(CameraManager manager, ErrorDisplayer errorDisplayer, 232fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraReadyListener readyListener) { 233fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mReadyHandler = new Handler(Looper.getMainLooper()); 234fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 235fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraThread = new HandlerThread("CameraOpsThread"); 236fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraThread.start(); 237fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 238fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (manager == null || errorDisplayer == null || 239fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford readyListener == null || mReadyHandler == null) { 240fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford throw new IllegalArgumentException("Need valid displayer, listener, handler"); 241fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 242fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 243fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraManager = manager; 244fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer = errorDisplayer; 245fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mReadyListener = readyListener; 246fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 247fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 248fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 249fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 250fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Open the first backfacing camera listed by the camera manager. 251fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Displays a dialog if it cannot open a camera. 252fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 253fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void openCamera(final String cameraId) { 254fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler = new Handler(mCameraThread.getLooper()); 255fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 256fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler.post(new Runnable() { 257fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 258fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (mCameraDevice != null) { 259fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford throw new IllegalStateException("Camera already open"); 260fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 261fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 262fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 263fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraManager.openCamera(cameraId, mCameraDeviceListener, mCameraHandler); 264fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 265fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = mErrorDisplayer.getErrorString(e); 266fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog(errorMessage); 267fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 268fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 269fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 270fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 271fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 272fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void pause() { 273fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford closeCameraAndWait(); 274fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundThread.quitSafely(); 275fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 276fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundThread.join(); 277fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundThread = null; 278fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mBackgroundHandler = null; 279fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (InterruptedException e) { 280fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford e.printStackTrace(); 281fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 282fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 283fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 284fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public Size getBestSize() { 285fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Find a good size for output - largest 16:9 aspect ratio that's less than 720p 286fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final int MAX_WIDTH = 1280; 287fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final float TARGET_ASPECT = 16.f / 9.f; 288fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final float ASPECT_TOLERANCE = 0.1f; 289fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 290fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 291fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford StreamConfigurationMap configs = 292fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraInfo.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 293fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 294fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Size[] outputSizes = configs.getOutputSizes(SurfaceHolder.class); 295fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 296fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Size outputSize = outputSizes[0]; 297fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford float outputAspect = (float) outputSize.getWidth() / outputSize.getHeight(); 298fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford for (Size candidateSize : outputSizes) { 299fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (candidateSize.getWidth() > MAX_WIDTH) continue; 300fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford float candidateAspect = (float) candidateSize.getWidth() / candidateSize.getHeight(); 301fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean goodCandidateAspect = 302fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Math.abs(candidateAspect - TARGET_ASPECT) < ASPECT_TOLERANCE; 303fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean goodOutputAspect = 304fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Math.abs(outputAspect - TARGET_ASPECT) < ASPECT_TOLERANCE; 305fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if ((goodCandidateAspect && !goodOutputAspect) || 306fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford candidateSize.getWidth() > outputSize.getWidth()) { 307fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford outputSize = candidateSize; 308fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford outputAspect = candidateAspect; 309fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 310fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 311fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return outputSize; 312fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 313fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 314fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 315fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Close the camera and wait for the close callback to be called in the camera thread. 316fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Times out after @{value CAMERA_CLOSE_TIMEOUT} ms. 317fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 318fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void closeCameraAndWait() { 319fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCloseWaiter.close(); 320fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler.post(mCloseCameraRunnable); 321fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford boolean closed = mCloseWaiter.block(CAMERA_CLOSE_TIMEOUT); 322fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (!closed) { 323fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Log.e(TAG, "Timeout closing camera"); 324fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 325fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 326fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 327fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private Runnable mCloseCameraRunnable = new Runnable() { 328fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 329fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (mCameraDevice != null) { 330fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice.close(); 331fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 332fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice = null; 333fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraSession = null; 334fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mSurfaces = null; 335fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 336fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 337fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 338fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 339fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Set the output Surfaces, and finish configuration if otherwise ready. 340fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 341fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setSurface(Surface surface) { 342fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final List<Surface> surfaceList = new ArrayList<Surface>(); 343fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford surfaceList.add(surface); 344fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford surfaceList.add(mImageReader.getSurface()); 345fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 346fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler.post(new Runnable() { 347fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 348fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mSurfaces = surfaceList; 349fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford startCameraSession(); 350fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 351fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 352fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 353fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 354fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 355fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Get a request builder for the current camera. 356fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 357fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public CaptureRequest.Builder createCaptureRequest(int template) throws CameraAccessException { 358fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraDevice device = mCameraDevice; 359fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (device == null) { 360fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford throw new IllegalStateException("Can't get requests when no camera is open"); 361fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 362fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return device.createCaptureRequest(template); 363fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 364fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 365fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 366fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Set a repeating request. 367fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 368fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setRepeatingRequest(final CaptureRequest request, 369fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final CameraCaptureSession.CaptureCallback listener, 370fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final Handler handler) { 371fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler.post(new Runnable() { 372fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 373fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 374fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraSession.setRepeatingRequest(request, listener, handler); 375fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 376fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = mErrorDisplayer.getErrorString(e); 377fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog(errorMessage); 378fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 379fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 380fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 381fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 382fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 383fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 384fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Set a repeating request. 385fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 386fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setRepeatingBurst(final List<CaptureRequest> requests, 387fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final CameraCaptureSession.CaptureCallback listener, 388fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final Handler handler) { 389fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler.post(new Runnable() { 390fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 391fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 392fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraSession.setRepeatingBurst(requests, listener, handler); 393fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 394fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 395fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = mErrorDisplayer.getErrorString(e); 396fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog(errorMessage); 397fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 398fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 399fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 400fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 401fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 402fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 403fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Configure the camera session. 404fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 405fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private void startCameraSession() { 406fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Wait until both the camera device is open and the SurfaceView is ready 407fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (mCameraDevice == null || mSurfaces == null) return; 408fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 409fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 410fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 411fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice.createCaptureSession( 412fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mSurfaces, mCameraSessionListener, mCameraHandler); 413fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 414fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = mErrorDisplayer.getErrorString(e); 415fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog(errorMessage); 416fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice.close(); 417fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice = null; 418fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 419fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 420fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 421fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 422fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Main listener for camera session events 423fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Invoked on mCameraThread 424fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 425fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private CameraCaptureSession.StateCallback mCameraSessionListener = 426fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford new CameraCaptureSession.StateCallback() { 427fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 428fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 429fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onConfigured(CameraCaptureSession session) { 430fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraSession = session; 431fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mReadyHandler.post(new Runnable() { 432fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 433fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // This can happen when the screen is turned off and turned back on. 434fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (null == mCameraDevice) { 435fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return; 436fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 437fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 438fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mReadyListener.onCameraReady(); 439fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 440fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 441fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 442fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 443fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 444fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 445fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onConfigureFailed(CameraCaptureSession session) { 446fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog("Unable to configure the capture session"); 447fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice.close(); 448fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice = null; 449fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 450fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 451fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 452fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 453fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Main listener for camera device events. 454fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Invoked on mCameraThread 455fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 456fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private CameraDevice.StateCallback mCameraDeviceListener = new CameraDevice.StateCallback() { 457fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 458fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 459fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onOpened(CameraDevice camera) { 460fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice = camera; 461fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford startCameraSession(); 462fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 463fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 464fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 465fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onClosed(CameraDevice camera) { 466fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCloseWaiter.open(); 467fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 468fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 469fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 470fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onDisconnected(CameraDevice camera) { 471fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog("The camera device has been disconnected."); 472fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford camera.close(); 473fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice = null; 474fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 475fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 476fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 477fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onError(CameraDevice camera, int error) { 478fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog("The camera encountered an error:" + error); 479fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford camera.close(); 480fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraDevice = null; 481fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 482fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 483fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 484fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 485fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void captureStillPicture(int currentJpegRotation, String name, ContentResolver resolver) { 486fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mSaveFileName = name; 487fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mContentResolver = resolver; 488fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 489fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // TODO call lock focus if we are in "AF-S(One-Shot AF) mode" 490fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // TODO call precapture if we are using flash 491fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // This is the CaptureRequest.Builder that we use to take a picture. 492fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final CaptureRequest.Builder captureBuilder = 493fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 494fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Log.v(TAG, " Target " + mImageReader.getWidth() + "," + mImageReader.getHeight()); 495fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 496fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford captureBuilder.addTarget(mImageReader.getSurface()); 497fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 498fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, currentJpegRotation); 499fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 500fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CameraCaptureSession.CaptureCallback captureCallback 501fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford = new CameraCaptureSession.CaptureCallback() { 502fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 503fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford @Override 504fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 505fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford TotalCaptureResult result) { 506fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Log.v(TAG, " onCaptureCompleted"); 507fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford setParameters(); 508fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 509fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 510fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 511fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 512fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford setRequest(captureBuilder.build(), captureCallback, null); 513fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 514fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford e.printStackTrace(); 515fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 516fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 517fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 518fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 519fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Set a repeating request. 520fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 521fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private void setRequest(final CaptureRequest request, 522fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final CameraCaptureSession.CaptureCallback listener, 523fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final Handler handler) { 524fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraHandler.post(new Runnable() { 525fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void run() { 526fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 527fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraSession.stopRepeating(); 528fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mCameraSession.capture(request, listener, handler); 529fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 530fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = mErrorDisplayer.getErrorString(e); 531fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mErrorDisplayer.showErrorDialog(errorMessage); 532fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 533fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 534fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }); 535fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 536fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 537fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setUpCamera(Surface processingNormalSurface) { 538fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mProcessingNormalSurface = processingNormalSurface; 539fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Ready to send requests in, so set them up 540fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 541fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CaptureRequest.Builder previewBuilder = 542fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 543fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford previewBuilder.addTarget(mProcessingNormalSurface); 544fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford previewBuilder.setTag(mAutoExposureTag); 545fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mPreviewRequest = previewBuilder.build(); 546fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder = createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 547fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AE_MODE, 548fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford CaptureRequest.CONTROL_AE_MODE_OFF); 549fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.addTarget(mProcessingNormalSurface); 550fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford setParameters(); 551fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 552fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (CameraAccessException e) { 553fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String errorMessage = e.getMessage(); 554fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // MessageDialogFragment.newInstance(errorMessage).show(getFragmentManager(), FRAGMENT_DIALOG); 555fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 556fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 557fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 558fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 559fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Start running an HDR burst on a configured camera session 560fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 561fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setParameters() { 562fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (mHdrBuilder == null) { 563fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Log.v(TAG," Camera not set up"); 564fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return; 565fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 566fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (mAutoExposure) { 567fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, ONE_SECOND / 30); 568fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, getExposure()); 569fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); 570fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } else { 571fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF); 572fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, ONE_SECOND / 30); 573fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, getExposure()); 574fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, getIso()); 575fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 576fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (mAutoFocus) { 577fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); 578fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); 579fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } else { 580fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF); 581fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, getFocusDistance()); 582fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mHdrBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START); 583fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 584fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 585fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford setRepeatingRequest(mHdrBuilder.build(), mCaptureCallback, mReadyHandler); 586fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 587fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 588fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private CameraCaptureSession.CaptureCallback mCaptureCallback 589fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford = new CameraCaptureSession.CaptureCallback() { 590fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 591fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, 592fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford TotalCaptureResult result) { 593fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 594fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 595fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 596fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 597fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Simple listener for main code to know the camera is ready for requests, or failed to 598fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * start. 599fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 600fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public interface CameraReadyListener { 601fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void onCameraReady(); 602fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 603fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 604fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 605fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Simple listener for displaying error messages 606fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 607fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public interface ErrorDisplayer { 608fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void showErrorDialog(String errorMessage); 609fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public String getErrorString(CameraAccessException e); 610fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 611fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 612fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public float getFocusDistance() { 613fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mFocusDist; 614fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 615fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 616fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setFocusDistance(float focusDistance) { 617fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mFocusDist = focusDistance; 618fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 619fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 620fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setIso(int iso) { 621fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mIso = iso; 622fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 623fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 624fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public boolean isAutoExposure() { 625fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mAutoExposure; 626fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 627fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 628fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setAutoExposure(boolean autoExposure) { 629fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mAutoExposure = autoExposure; 630fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 631fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 632fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public boolean isAutoFocus() { 633fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mAutoFocus; 634fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 635fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 636fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setAutoFocus(boolean autoFocus) { 637fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mAutoFocus = autoFocus; 638fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 639fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 640fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public int getIso() { 641fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mIso; 642fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 643fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 644fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public long getExposure() { 645fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mExposure; 646fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 647fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 648fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void setExposure(long exposure) { 649fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford mExposure = exposure; 650fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 651fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 652fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public int getIsoMax() { 653fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mISOmax; 654fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 655fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 656fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public int getIsoMin() { 657fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mISOmin; 658fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 659fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 660fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public long getExpMax() { 661fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mExpMax; 662fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 663fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 664fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public long getExpMin() { 665fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mExpMin; 666fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 667fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 668fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public float getFocusMin() { 669fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return mFocusMin; 670fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 671fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford}