Home | History | Annotate | Download | only in initialization
      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