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 */ 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 157 public OneCamera provideOneCamera() { 158 return mOneCamera; 159 } 160 } 161