Home | History | Annotate | Download | only in v2
      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;
     18 
     19 import android.annotation.TargetApi;
     20 import android.graphics.ImageFormat;
     21 import android.hardware.camera2.CameraDevice;
     22 import android.hardware.camera2.CaptureRequest;
     23 import android.os.Build;
     24 import android.view.Surface;
     25 
     26 import com.android.camera.FatalErrorHandler;
     27 import com.android.camera.async.HandlerFactory;
     28 import com.android.camera.async.Lifetime;
     29 import com.android.camera.async.MainThread;
     30 import com.android.camera.async.Observable;
     31 import com.android.camera.async.Observables;
     32 import com.android.camera.async.Updatable;
     33 import com.android.camera.burst.BurstFacade;
     34 import com.android.camera.debug.Loggers;
     35 import com.android.camera.one.OneCamera;
     36 import com.android.camera.one.OneCameraCharacteristics;
     37 import com.android.camera.one.config.OneCameraFeatureConfig;
     38 import com.android.camera.one.v2.camera2proxy.AndroidImageReaderProxy;
     39 import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
     40 import com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
     41 import com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory;
     42 import com.android.camera.one.v2.camera2proxy.ImageReaderProxy;
     43 import com.android.camera.one.v2.camera2proxy.TotalCaptureResultProxy;
     44 import com.android.camera.one.v2.commands.CameraCommandExecutor;
     45 import com.android.camera.one.v2.commands.BasicPreviewCommandFactory;
     46 import com.android.camera.one.v2.common.BasicCameraFactory;
     47 import com.android.camera.one.v2.common.SimpleCaptureStream;
     48 import com.android.camera.one.v2.core.FrameServer;
     49 import com.android.camera.one.v2.core.FrameServerFactory;
     50 import com.android.camera.one.v2.core.RequestBuilder;
     51 import com.android.camera.one.v2.core.RequestTemplate;
     52 import com.android.camera.one.v2.core.ResponseListeners;
     53 import com.android.camera.one.v2.errorhandling.FramerateJankDetector;
     54 import com.android.camera.one.v2.imagesaver.ImageSaver;
     55 import com.android.camera.one.v2.initialization.CameraStarter;
     56 import com.android.camera.one.v2.initialization.InitializedOneCameraFactory;
     57 import com.android.camera.one.v2.photo.ImageRotationCalculator;
     58 import com.android.camera.one.v2.photo.LegacyPictureTakerFactory;
     59 import com.android.camera.one.v2.photo.PictureTaker;
     60 import com.android.camera.one.v2.photo.PictureTakerFactory;
     61 import com.android.camera.one.v2.sharedimagereader.ManagedImageReader;
     62 import com.android.camera.one.v2.sharedimagereader.SharedImageReaderFactory;
     63 import com.android.camera.stats.UsageStatistics;
     64 import com.android.camera.util.AndroidContext;
     65 import com.android.camera.util.GservicesHelper;
     66 import com.android.camera.util.Provider;
     67 import com.android.camera.util.Size;
     68 import com.google.common.base.Supplier;
     69 
     70 import java.util.ArrayList;
     71 import java.util.Arrays;
     72 import java.util.List;
     73 import java.util.concurrent.ExecutorService;
     74 import java.util.concurrent.Executors;
     75 
     76 /**
     77  * Creates a camera which takes jpeg images using the hardware encoder with
     78  * baseline functionality.
     79  */
     80 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     81 public class SimpleOneCameraFactory implements OneCameraFactory {
     82     private final int mImageFormat;
     83     private final int mMaxImageCount;
     84     private final ImageRotationCalculator mImageRotationCalculator;
     85 
     86     /**
     87      * @param imageFormat The {@link ImageFormat} to use for full-size images to
     88      *            be saved.
     89      * @param maxImageCount The size of the image reader to use for full-size
     90      *            images.
     91      */
     92     public SimpleOneCameraFactory(int imageFormat, int maxImageCount,
     93             ImageRotationCalculator imageRotationCalculator) {
     94         mImageFormat = imageFormat;
     95         mMaxImageCount = maxImageCount;
     96         mImageRotationCalculator = imageRotationCalculator;
     97     }
     98 
     99     @Override
    100     public OneCamera createOneCamera(final CameraDeviceProxy device,
    101             final OneCameraCharacteristics characteristics,
    102             final OneCameraFeatureConfig.CaptureSupportLevel supportLevel,
    103             final MainThread mainExecutor,
    104             final Size pictureSize,
    105             final ImageSaver.Builder imageSaverBuilder,
    106             final Observable<OneCamera.PhotoCaptureParameters.Flash> flashSetting,
    107             final Observable<Integer> exposureSetting,
    108             final Observable<Boolean> hdrSceneSetting,
    109             final BurstFacade burstFacade,
    110             final FatalErrorHandler fatalErrorHandler) {
    111         final Lifetime lifetime = new Lifetime();
    112 
    113         final ImageReaderProxy imageReader = new CloseWhenDoneImageReader(new LoggingImageReader(
    114                 AndroidImageReaderProxy.newInstance(
    115                         pictureSize.getWidth(), pictureSize.getHeight(),
    116                         mImageFormat, mMaxImageCount),
    117                 Loggers.tagFactory()));
    118 
    119         lifetime.add(imageReader);
    120         lifetime.add(device);
    121 
    122         List<Surface> outputSurfaces = new ArrayList<>();
    123         outputSurfaces.add(imageReader.getSurface());
    124 
    125         /**
    126          * Finishes constructing the camera when prerequisites, e.g. the preview
    127          * stream and capture session, are ready.
    128          */
    129         CameraStarter cameraStarter = new CameraStarter() {
    130             @Override
    131             public CameraStarter.CameraControls startCamera(Lifetime cameraLifetime,
    132                     CameraCaptureSessionProxy cameraCaptureSession,
    133                     Surface previewSurface,
    134                     Observable<Float> zoomState,
    135                     Updatable<TotalCaptureResultProxy> metadataCallback,
    136                     Updatable<Boolean> readyState) {
    137                 // Create the FrameServer from the CaptureSession.
    138                 FrameServerFactory frameServerComponent = new FrameServerFactory(
    139                         new Lifetime(cameraLifetime), cameraCaptureSession, new HandlerFactory());
    140 
    141                 CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(
    142                         Loggers.tagFactory(),
    143                         new Provider<ExecutorService>() {
    144                             @Override
    145                             public ExecutorService get() {
    146                                 // Use a dynamically-expanding thread pool to
    147                                 // allow any number of commands to execute
    148                                 // simultaneously.
    149                                 return Executors.newCachedThreadPool();
    150                             }
    151                         });
    152 
    153                 // Create the shared image reader.
    154                 SharedImageReaderFactory sharedImageReaderFactory =
    155                         new SharedImageReaderFactory(new Lifetime(cameraLifetime), imageReader,
    156                                 new HandlerFactory());
    157                 Updatable<Long> globalTimestampCallback =
    158                         sharedImageReaderFactory.provideGlobalTimestampQueue();
    159                 ManagedImageReader managedImageReader =
    160                         sharedImageReaderFactory.provideSharedImageReader();
    161 
    162                 // Create the request builder used by all camera operations.
    163                 // Streams, ResponseListeners, and Parameters added to
    164                 // this will be applied to *all* requests sent to the camera.
    165                 RequestTemplate rootBuilder = new RequestTemplate
    166                         (new CameraDeviceRequestBuilderFactory(device));
    167                 // The shared image reader must be wired to receive every
    168                 // timestamp for every image (including the preview).
    169                 rootBuilder.addResponseListener(
    170                         ResponseListeners.forTimestamps(globalTimestampCallback));
    171                 rootBuilder.addStream(new SimpleCaptureStream(previewSurface));
    172                 rootBuilder.addResponseListener(ResponseListeners.forFinalMetadata(
    173                         metadataCallback));
    174 
    175                 FrameServer ephemeralFrameServer =
    176                       frameServerComponent.provideEphemeralFrameServer();
    177 
    178                 // Create basic functionality (zoom, AE, AF).
    179                 BasicCameraFactory basicCameraFactory = new BasicCameraFactory(new Lifetime
    180                         (cameraLifetime),
    181                         characteristics,
    182                         ephemeralFrameServer,
    183                         rootBuilder,
    184                         cameraCommandExecutor,
    185                         new BasicPreviewCommandFactory(ephemeralFrameServer),
    186                         flashSetting,
    187                         exposureSetting,
    188                         zoomState,
    189                         hdrSceneSetting,
    190                         CameraDevice.TEMPLATE_PREVIEW);
    191 
    192                 // Register the dynamic updater via orientation supplier
    193                 rootBuilder.setParam(CaptureRequest.JPEG_ORIENTATION,
    194                         mImageRotationCalculator.getSupplier());
    195 
    196                 if (GservicesHelper.isJankStatisticsEnabled(AndroidContext.instance().get()
    197                       .getContentResolver())) {
    198                     rootBuilder.addResponseListener(
    199                           new FramerateJankDetector(Loggers.tagFactory(),
    200                                 UsageStatistics.instance()));
    201                 }
    202 
    203                 RequestBuilder.Factory meteredZoomedRequestBuilder =
    204                         basicCameraFactory.provideMeteredZoomedRequestBuilder();
    205 
    206                 // Create the picture-taker.
    207                 PictureTaker pictureTaker;
    208                 if (supportLevel == OneCameraFeatureConfig.CaptureSupportLevel.LEGACY_JPEG) {
    209                     pictureTaker = new LegacyPictureTakerFactory(imageSaverBuilder,
    210                             cameraCommandExecutor, mainExecutor,
    211                             frameServerComponent.provideFrameServer(),
    212                             meteredZoomedRequestBuilder, managedImageReader).providePictureTaker();
    213                 } else {
    214                     pictureTaker = PictureTakerFactory.create(Loggers.tagFactory(), mainExecutor,
    215                             cameraCommandExecutor, imageSaverBuilder,
    216                             frameServerComponent.provideFrameServer(),
    217                             meteredZoomedRequestBuilder, managedImageReader, flashSetting)
    218                             .providePictureTaker();
    219                 }
    220 
    221                 // Wire-together ready-state.
    222                 final Observable<Integer> availableImageCount = sharedImageReaderFactory
    223                         .provideAvailableImageCount();
    224                 final Observable<Boolean> frameServerAvailability = frameServerComponent
    225                         .provideReadyState();
    226                 Observable<Boolean> ready = Observables.transform(
    227                         Arrays.asList(availableImageCount, frameServerAvailability),
    228                         new Supplier<Boolean>() {
    229                             @Override
    230                             public Boolean get() {
    231                                 boolean atLeastOneImageAvailable = availableImageCount.get() >= 1;
    232                                 boolean frameServerAvailable = frameServerAvailability.get();
    233                                 return atLeastOneImageAvailable && frameServerAvailable;
    234                             }
    235                         });
    236 
    237                 lifetime.add(Observables.addThreadSafeCallback(ready, readyState));
    238 
    239                 basicCameraFactory.providePreviewUpdater().run();
    240 
    241                 return new CameraStarter.CameraControls(
    242                         pictureTaker,
    243                         basicCameraFactory.provideManualAutoFocus());
    244             }
    245         };
    246 
    247         float maxZoom = characteristics.getAvailableMaxDigitalZoom();
    248         List<Size> supportedPreviewSizes = characteristics.getSupportedPreviewSizes();
    249         OneCamera.Facing direction = characteristics.getCameraDirection();
    250 
    251         return new InitializedOneCameraFactory(lifetime, cameraStarter, device, outputSurfaces,
    252                 mainExecutor, new HandlerFactory(), maxZoom, supportedPreviewSizes,
    253                 characteristics.getLensFocusRange(), direction)
    254                 .provideOneCamera();
    255     }
    256 }
    257