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.annotation.TargetApi;
20 import android.hardware.camera2.CaptureResult;
21 import android.os.Build;
22 import android.os.Handler;
23 import android.view.Surface;
24 
25 import com.android.camera.async.ConcurrentState;
26 import com.android.camera.async.FilteredUpdatable;
27 import com.android.camera.async.HandlerFactory;
28 import com.android.camera.async.Lifetime;
29 import com.android.camera.async.Listenable;
30 import com.android.camera.async.MainThread;
31 import com.android.camera.one.OneCamera;
32 import com.android.camera.one.PreviewSizeSelector;
33 import com.android.camera.one.v2.autofocus.ManualAutoFocus;
34 import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
35 import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
36 import com.android.camera.one.v2.photo.PictureTaker;
37 import com.android.camera.ui.motion.LinearScale;
38 import com.android.camera.util.Size;
39 import com.google.common.util.concurrent.SettableFuture;
40 
41 import java.util.List;
42 import java.util.concurrent.Executor;
43 
44 /**
45  * Simplifies the construction of OneCamera instances which use the camera2 API
46  * by handling the initialization sequence.
47  * <p>
48  * The type of camera created is specified by a {@link CameraStarter}.
49  * <p>
50  * This manages camera startup, which is nontrivial because it requires the
51  * asynchronous acquisition of several dependencies:
52  * <ol>
53  * <li>The camera2 CameraDevice, which is available immediately.</li>
54  * <li>The preview Surface, which is available after
55  * {@link OneCamera#startPreview} is called.</li>
56  * <li>The camera2 CameraCaptureSession, created asynchronously using the
57  * CameraDevice and preview Surface.</li>
58  * </ol>
59  */
60 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
61 public class InitializedOneCameraFactory {
62     private final GenericOneCameraImpl mOneCamera;
63 
64     /**
65      * @param cameraStarter Starts the camera, after initialization of the
66      *            preview stream and capture session is complete.
67      * @param outputSurfaces The set of output Surfaces (excluding the
68      *            not-yet-available preview Surface) to use when configuring the
69      *            capture session.
70      */
InitializedOneCameraFactory( final Lifetime lifetime, final CameraStarter cameraStarter, CameraDeviceProxy device, List<Surface> outputSurfaces, MainThread mainThreadExecutor, HandlerFactory handlerFactory, float maxZoom, List<Size> supportedPreviewSizes, LinearScale lensRange, OneCamera.Facing direction)71     public InitializedOneCameraFactory(
72             final Lifetime lifetime, final CameraStarter cameraStarter, CameraDeviceProxy device,
73             List<Surface> outputSurfaces, MainThread mainThreadExecutor,
74             HandlerFactory handlerFactory, float maxZoom, List<Size> supportedPreviewSizes,
75             LinearScale lensRange, OneCamera.Facing direction) {
76         // Assembles and returns a OneCamera based on the CameraStarter.
77 
78         // Create/wrap required threads.
79         final Handler cameraHandler = handlerFactory.create(lifetime, "CameraHandler");
80 
81         // Since we cannot create an actual PictureTaker and ManualAutoFocus
82         // until the CaptureSession is available, so create ones which defer to
83         // a Future of the actual implementation.
84         final SettableFuture<PictureTaker> mPictureTaker = SettableFuture.create();
85         PictureTaker pictureTaker = new DeferredPictureTaker(mPictureTaker);
86 
87         final SettableFuture<ManualAutoFocus> mManualAutoFocus = SettableFuture.create();
88         ManualAutoFocus manualAutoFocus = new DeferredManualAutoFocus(
89                 mManualAutoFocus);
90 
91         // The OneCamera interface exposes various types of state, either
92         // through getters, setters, or the ability to register listeners.
93         // Since these values are interacted with by multiple threads, we can
94         // use {@link ConcurrentState} to provide this functionality safely.
95         final ConcurrentState<Float> zoomState = new ConcurrentState<>(1.0f);
96         final ConcurrentState<Integer> afState = new ConcurrentState<>(
97                 CaptureResult.CONTROL_AF_STATE_INACTIVE);
98         final ConcurrentState<OneCamera.FocusState> focusState = new ConcurrentState<>(new
99                 OneCamera.FocusState(0.0f, false));
100         final ConcurrentState<Integer> afMode = new ConcurrentState<>(CaptureResult
101                 .CONTROL_AF_MODE_OFF);
102         final ConcurrentState<Boolean> readyState = new ConcurrentState<>(false);
103 
104         // Wrap state to be able to register listeners which run on the main
105         // thread.
106         Listenable<Integer> afStateListenable = new Listenable<>(afState,
107                 mainThreadExecutor);
108         Listenable<OneCamera.FocusState> focusStateListenable = new Listenable<>(
109                 focusState, mainThreadExecutor);
110         Listenable<Boolean> readyStateListenable = new Listenable<>(readyState,
111                 mainThreadExecutor);
112 
113         // Wrap each value in a filter to ensure that only differences pass
114         // through.
115         final MetadataCallback metadataCallback = new MetadataCallback(
116                 new FilteredUpdatable<>(afState),
117                 new FilteredUpdatable<>(focusState),
118                 new FilteredUpdatable<>(afMode));
119 
120         // The following handles the initialization sequence in which we receive
121         // various dependencies at different times in the following sequence:
122         // 1. CameraDevice
123         // 2. The Surface on which to render the preview stream
124         // 3. The CaptureSession
125         // When all three of these are available, the {@link #CameraFactory} can
126         // be used to assemble the actual camera functionality (e.g. to take
127         // pictures, and run AF scans).
128 
129         // Note that these must be created in reverse-order to when they are run
130         // because each stage depends on the previous one.
131         final CaptureSessionCreator captureSessionCreator = new CaptureSessionCreator(device,
132                 cameraHandler);
133 
134         PreviewStarter mPreviewStarter = new PreviewStarter(outputSurfaces,
135                 captureSessionCreator,
136                 new PreviewStarter.CameraCaptureSessionCreatedListener() {
137                     @Override
138                     public void onCameraCaptureSessionCreated(CameraCaptureSessionProxy session,
139                             Surface previewSurface) {
140                         CameraStarter.CameraControls controls = cameraStarter.startCamera(
141                                 new Lifetime(lifetime),
142                                 session, previewSurface,
143                                 zoomState, metadataCallback, readyState);
144                         mPictureTaker.set(controls.getPictureTaker());
145                         mManualAutoFocus.set(controls.getManualAutoFocus());
146                     }
147                 });
148 
149         PreviewSizeSelector previewSizeSelector =
150               new Camera2PreviewSizeSelector(supportedPreviewSizes);
151 
152         mOneCamera = new GenericOneCameraImpl(lifetime, pictureTaker, manualAutoFocus, lensRange,
153                 mainThreadExecutor, afStateListenable, focusStateListenable, readyStateListenable,
154                 maxZoom, zoomState, direction, previewSizeSelector, mPreviewStarter);
155     }
156 
provideOneCamera()157     public OneCamera provideOneCamera() {
158         return mOneCamera;
159     }
160 }
161