1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.one.v2.initialization; 18 19 import android.app.Activity; 20 import android.view.Surface; 21 22 import com.android.camera.async.FilteredCallback; 23 import com.android.camera.async.Listenable; 24 import com.android.camera.async.SafeCloseable; 25 import com.android.camera.async.Updatable; 26 import com.android.camera.one.OneCamera; 27 import com.android.camera.one.PreviewSizeSelector; 28 import com.android.camera.one.v2.AutoFocusHelper; 29 import com.android.camera.one.v2.autofocus.ManualAutoFocus; 30 import com.android.camera.one.v2.photo.PictureTaker; 31 import com.android.camera.session.CaptureSession; 32 import com.android.camera.ui.motion.LinearScale; 33 import com.android.camera.util.Callback; 34 import com.android.camera.util.Size; 35 import com.google.common.util.concurrent.FutureCallback; 36 import com.google.common.util.concurrent.Futures; 37 import com.google.common.util.concurrent.ListenableFuture; 38 import com.google.common.util.concurrent.MoreExecutors; 39 40 import java.util.concurrent.Executor; 41 42 import javax.annotation.Nonnull; 43 44 /** 45 * A generic, composable {@link OneCamera}. 46 * <p> 47 * Note: This implementation assumes that these four methods are invoked in 48 * sequences matching the following regex: 49 * <p> 50 * startPreview (takePicture | triggerFocusAndMeterAtPoint)* close 51 * <p> 52 * All other methods may be called at any time. 53 */ 54 class GenericOneCameraImpl implements OneCamera { 55 56 private final SafeCloseable mCloseListener; 57 private final PictureTaker mPictureTaker; 58 private final ManualAutoFocus mManualAutoFocus; 59 private final LinearScale mLensRange; 60 private final Executor mMainExecutor; 61 private final Listenable<Integer> mAFStateListenable; 62 private final Listenable<FocusState> mFocusStateListenable; 63 private final Listenable<Boolean> mReadyStateListenable; 64 private final float mMaxZoom; 65 private final Updatable<Float> mZoom; 66 private final Facing mDirection; 67 private final PreviewSizeSelector mPreviewSizeSelector; 68 private final PreviewStarter mPreviewStarter; 69 GenericOneCameraImpl(SafeCloseable closeListener, PictureTaker pictureTaker, ManualAutoFocus manualAutoFocus, LinearScale lensRange, Executor mainExecutor, Listenable<Integer> afStateProvider, Listenable<FocusState> focusStateProvider, Listenable<Boolean> readyStateListenable, float maxZoom, Updatable<Float> zoom, Facing direction, PreviewSizeSelector previewSizeSelector, PreviewStarter previewStarter)70 public GenericOneCameraImpl(SafeCloseable closeListener, PictureTaker pictureTaker, 71 ManualAutoFocus manualAutoFocus, LinearScale lensRange, Executor mainExecutor, 72 Listenable<Integer> afStateProvider, Listenable<FocusState> focusStateProvider, 73 Listenable<Boolean> readyStateListenable, float maxZoom, Updatable<Float> zoom, 74 Facing direction, PreviewSizeSelector previewSizeSelector, 75 PreviewStarter previewStarter) { 76 mCloseListener = closeListener; 77 mMainExecutor = mainExecutor; 78 mMaxZoom = maxZoom; 79 mDirection = direction; 80 mPreviewSizeSelector = previewSizeSelector; 81 mPictureTaker = pictureTaker; 82 mManualAutoFocus = manualAutoFocus; 83 mLensRange = lensRange; 84 mAFStateListenable = afStateProvider; 85 mFocusStateListenable = focusStateProvider; 86 mReadyStateListenable = readyStateListenable; 87 mZoom = zoom; 88 mPreviewStarter = previewStarter; 89 } 90 91 @Override triggerFocusAndMeterAtPoint(float nx, float ny)92 public void triggerFocusAndMeterAtPoint(float nx, float ny) { 93 mManualAutoFocus.triggerFocusAndMeterAtPoint(nx, ny); 94 } 95 96 @Override takePicture(PhotoCaptureParameters params, CaptureSession session)97 public void takePicture(PhotoCaptureParameters params, CaptureSession session) { 98 mPictureTaker.takePicture(params, session); 99 } 100 101 @Override setFocusStateListener(final FocusStateListener listener)102 public void setFocusStateListener(final FocusStateListener listener) { 103 mAFStateListenable.setCallback(new Callback<Integer>() { 104 @Override 105 public void onCallback(@Nonnull Integer afState) { 106 // TODO delete frameNumber from FocusStateListener callback. It 107 // is optional and never actually used. 108 long frameNumber = -1; 109 if(listener !=null) { 110 listener.onFocusStatusUpdate(AutoFocusHelper.stateFromCamera2State(afState), 111 frameNumber); 112 } 113 } 114 }); 115 } 116 117 @Override setFocusDistanceListener(final FocusDistanceListener listener)118 public void setFocusDistanceListener(final FocusDistanceListener listener) { 119 if (listener == null) { 120 mFocusStateListenable.clear(); 121 return; 122 } 123 mFocusStateListenable.setCallback(new Callback<FocusState>() { 124 @Override 125 public void onCallback(@Nonnull FocusState focusState) { 126 if (focusState.isActive) { 127 listener.onFocusDistance(focusState.lensDistance, mLensRange); 128 } 129 } 130 }); 131 } 132 133 @Override setReadyStateChangedListener(final ReadyStateChangedListener listener)134 public void setReadyStateChangedListener(final ReadyStateChangedListener listener) { 135 if (listener == null) { 136 mReadyStateListenable.clear(); 137 return; 138 } 139 140 Callback<Boolean> readyStateCallback = new Callback<Boolean>() { 141 @Override 142 public void onCallback(@Nonnull Boolean result) { 143 listener.onReadyStateChanged(result); 144 } 145 }; 146 147 mReadyStateListenable.setCallback(new FilteredCallback<>(readyStateCallback)); 148 } 149 150 @Override startPreview(Surface surface, final CaptureReadyCallback listener)151 public void startPreview(Surface surface, final CaptureReadyCallback listener) { 152 ListenableFuture<Void> result = mPreviewStarter.startPreview(surface); 153 Futures.addCallback(result, new FutureCallback<Void>() { 154 @Override 155 public void onSuccess(@Nonnull Void aVoid) { 156 listener.onReadyForCapture(); 157 } 158 159 @Override 160 public void onFailure(@Nonnull Throwable throwable) { 161 listener.onSetupFailed(); 162 } 163 }, MoreExecutors.directExecutor()); 164 } 165 166 @Override close()167 public void close() { 168 mCloseListener.close(); 169 } 170 171 @Override getDirection()172 public Facing getDirection() { 173 return mDirection; 174 } 175 176 @Override getMaxZoom()177 public float getMaxZoom() { 178 return mMaxZoom; 179 } 180 181 @Override setZoom(float zoom)182 public void setZoom(float zoom) { 183 mZoom.update(zoom); 184 } 185 186 @Override pickPreviewSize(Size pictureSize, Activity context)187 public Size pickPreviewSize(Size pictureSize, Activity context) { 188 return mPreviewSizeSelector.pickPreviewSize(pictureSize); 189 } 190 } 191