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.content.Context; 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 39 import java.util.concurrent.Executor; 40 41 import javax.annotation.Nonnull; 42 43 /** 44 * A generic, composable {@link OneCamera}. 45 * <p> 46 * Note: This implementation assumes that these four methods are invoked in 47 * sequences matching the following regex: 48 * <p> 49 * startPreview (takePicture | triggerFocusAndMeterAtPoint)* close 50 * <p> 51 * All other methods may be called at any time. 52 */ 53 class GenericOneCameraImpl implements OneCamera { 54 55 private final SafeCloseable mCloseListener; 56 private final PictureTaker mPictureTaker; 57 private final ManualAutoFocus mManualAutoFocus; 58 private final LinearScale mLensRange; 59 private final Executor mMainExecutor; 60 private final Listenable<Integer> mAFStateListenable; 61 private final Listenable<FocusState> mFocusStateListenable; 62 private final Listenable<Boolean> mReadyStateListenable; 63 private final float mMaxZoom; 64 private final Updatable<Float> mZoom; 65 private final Facing mDirection; 66 private final PreviewSizeSelector mPreviewSizeSelector; 67 private final PreviewStarter mPreviewStarter; 68 69 public GenericOneCameraImpl(SafeCloseable closeListener, PictureTaker pictureTaker, 70 ManualAutoFocus manualAutoFocus, LinearScale lensRange, Executor mainExecutor, 71 Listenable<Integer> afStateProvider, Listenable<FocusState> focusStateProvider, 72 Listenable<Boolean> readyStateListenable, float maxZoom, Updatable<Float> zoom, 73 Facing direction, PreviewSizeSelector previewSizeSelector, 74 PreviewStarter previewStarter) { 75 mCloseListener = closeListener; 76 mMainExecutor = mainExecutor; 77 mMaxZoom = maxZoom; 78 mDirection = direction; 79 mPreviewSizeSelector = previewSizeSelector; 80 mPictureTaker = pictureTaker; 81 mManualAutoFocus = manualAutoFocus; 82 mLensRange = lensRange; 83 mAFStateListenable = afStateProvider; 84 mFocusStateListenable = focusStateProvider; 85 mReadyStateListenable = readyStateListenable; 86 mZoom = zoom; 87 mPreviewStarter = previewStarter; 88 } 89 90 @Override 91 public void triggerFocusAndMeterAtPoint(float nx, float ny) { 92 mManualAutoFocus.triggerFocusAndMeterAtPoint(nx, ny); 93 } 94 95 @Override 96 public void takePicture(PhotoCaptureParameters params, CaptureSession session) { 97 mPictureTaker.takePicture(params, session); 98 } 99 100 @Override 101 public void setFocusStateListener(final FocusStateListener listener) { 102 mAFStateListenable.setCallback(new Callback<Integer>() { 103 @Override 104 public void onCallback(@Nonnull Integer afState) { 105 // TODO delete frameNumber from FocusStateListener callback. It 106 // is optional and never actually used. 107 long frameNumber = -1; 108 if(listener !=null) { 109 listener.onFocusStatusUpdate(AutoFocusHelper.stateFromCamera2State(afState), 110 frameNumber); 111 } 112 } 113 }); 114 } 115 116 @Override 117 public void setFocusDistanceListener(final FocusDistanceListener listener) { 118 if (listener == null) { 119 mFocusStateListenable.clear(); 120 return; 121 } 122 mFocusStateListenable.setCallback(new Callback<FocusState>() { 123 @Override 124 public void onCallback(@Nonnull FocusState focusState) { 125 if (focusState.isActive) { 126 listener.onFocusDistance(focusState.lensDistance, mLensRange); 127 } 128 } 129 }); 130 } 131 132 @Override 133 public void setReadyStateChangedListener(final ReadyStateChangedListener listener) { 134 if (listener == null) { 135 mReadyStateListenable.clear(); 136 return; 137 } 138 139 Callback<Boolean> readyStateCallback = new Callback<Boolean>() { 140 @Override 141 public void onCallback(@Nonnull Boolean result) { 142 listener.onReadyStateChanged(result); 143 } 144 }; 145 146 mReadyStateListenable.setCallback(new FilteredCallback<>(readyStateCallback)); 147 } 148 149 @Override 150 public void startPreview(Surface surface, final CaptureReadyCallback listener) { 151 ListenableFuture<Void> result = mPreviewStarter.startPreview(surface); 152 Futures.addCallback(result, new FutureCallback<Void>() { 153 @Override 154 public void onSuccess(@Nonnull Void aVoid) { 155 listener.onReadyForCapture(); 156 } 157 158 @Override 159 public void onFailure(@Nonnull Throwable throwable) { 160 listener.onSetupFailed(); 161 } 162 }); 163 } 164 165 @Override 166 public void close() { 167 mCloseListener.close(); 168 } 169 170 @Override 171 public Facing getDirection() { 172 return mDirection; 173 } 174 175 @Override 176 public float getMaxZoom() { 177 return mMaxZoom; 178 } 179 180 @Override 181 public void setZoom(float zoom) { 182 mZoom.update(zoom); 183 } 184 185 @Override 186 public Size pickPreviewSize(Size pictureSize, Context context) { 187 return mPreviewSizeSelector.pickPreviewSize(pictureSize); 188 } 189 } 190