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.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