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 
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)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
triggerFocusAndMeterAtPoint(float nx, float ny)91     public void triggerFocusAndMeterAtPoint(float nx, float ny) {
92         mManualAutoFocus.triggerFocusAndMeterAtPoint(nx, ny);
93     }
94 
95     @Override
takePicture(PhotoCaptureParameters params, CaptureSession session)96     public void takePicture(PhotoCaptureParameters params, CaptureSession session) {
97         mPictureTaker.takePicture(params, session);
98     }
99 
100     @Override
setFocusStateListener(final FocusStateListener listener)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
setFocusDistanceListener(final FocusDistanceListener listener)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
setReadyStateChangedListener(final ReadyStateChangedListener listener)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
startPreview(Surface surface, final CaptureReadyCallback listener)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
close()166     public void close() {
167         mCloseListener.close();
168     }
169 
170     @Override
getDirection()171     public Facing getDirection() {
172         return mDirection;
173     }
174 
175     @Override
getMaxZoom()176     public float getMaxZoom() {
177         return mMaxZoom;
178     }
179 
180     @Override
setZoom(float zoom)181     public void setZoom(float zoom) {
182         mZoom.update(zoom);
183     }
184 
185     @Override
pickPreviewSize(Size pictureSize, Context context)186     public Size pickPreviewSize(Size pictureSize, Context context) {
187         return mPreviewSizeSelector.pickPreviewSize(pictureSize);
188     }
189 }
190