112f608f3d2089439a108788a1908941eea4277b9Puneet Lall/*
212f608f3d2089439a108788a1908941eea4277b9Puneet Lall * Copyright (C) 2014 The Android Open Source Project
312f608f3d2089439a108788a1908941eea4277b9Puneet Lall *
412f608f3d2089439a108788a1908941eea4277b9Puneet Lall * Licensed under the Apache License, Version 2.0 (the "License");
512f608f3d2089439a108788a1908941eea4277b9Puneet Lall * you may not use this file except in compliance with the License.
612f608f3d2089439a108788a1908941eea4277b9Puneet Lall * You may obtain a copy of the License at
712f608f3d2089439a108788a1908941eea4277b9Puneet Lall *
812f608f3d2089439a108788a1908941eea4277b9Puneet Lall *      http://www.apache.org/licenses/LICENSE-2.0
912f608f3d2089439a108788a1908941eea4277b9Puneet Lall *
1012f608f3d2089439a108788a1908941eea4277b9Puneet Lall * Unless required by applicable law or agreed to in writing, software
1112f608f3d2089439a108788a1908941eea4277b9Puneet Lall * distributed under the License is distributed on an "AS IS" BASIS,
1212f608f3d2089439a108788a1908941eea4277b9Puneet Lall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1312f608f3d2089439a108788a1908941eea4277b9Puneet Lall * See the License for the specific language governing permissions and
1412f608f3d2089439a108788a1908941eea4277b9Puneet Lall * limitations under the License.
1512f608f3d2089439a108788a1908941eea4277b9Puneet Lall */
1612f608f3d2089439a108788a1908941eea4277b9Puneet Lall
1712f608f3d2089439a108788a1908941eea4277b9Puneet Lallpackage com.android.camera.one.v2;
1812f608f3d2089439a108788a1908941eea4277b9Puneet Lall
195f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport android.annotation.TargetApi;
2012f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport android.hardware.camera2.CameraDevice;
21593a03b147a0388530cc63ca83e23fea6107693fI-Jong Linimport android.hardware.camera2.CaptureRequest;
225f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport android.os.Build.VERSION_CODES;
23593a03b147a0388530cc63ca83e23fea6107693fI-Jong Linimport android.util.Range;
2412f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport android.view.Surface;
2512f608f3d2089439a108788a1908941eea4277b9Puneet Lall
2666b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lallimport com.android.camera.FatalErrorHandler;
27d8463954727c9f8b688e69476439830cadb7b45aPuneet Lallimport com.android.camera.async.HandlerFactory;
2812f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.async.Lifetime;
29386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lallimport com.android.camera.async.MainThread;
30d8463954727c9f8b688e69476439830cadb7b45aPuneet Lallimport com.android.camera.async.Observable;
3163204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lallimport com.android.camera.async.Observables;
3212f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.async.Updatable;
33b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekharimport com.android.camera.burst.BurstFacade;
34b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekharimport com.android.camera.burst.BurstTaker;
35b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekharimport com.android.camera.burst.BurstTakerImpl;
360db8a2fd5cc02753d42f34a1c858b980c6c277bbPaul Rohdeimport com.android.camera.debug.Log.Tag;
370db8a2fd5cc02753d42f34a1c858b980c6c277bbPaul Rohdeimport com.android.camera.debug.Logger;
380db8a2fd5cc02753d42f34a1c858b980c6c277bbPaul Rohdeimport com.android.camera.debug.Loggers;
3912f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.OneCamera;
40d8463954727c9f8b688e69476439830cadb7b45aPuneet Lallimport com.android.camera.one.OneCameraCharacteristics;
418f51086c8177056345de996963515c4bd3415254Sascha Haeberlingimport com.android.camera.one.config.OneCameraFeatureConfig.CaptureSupportLevel;
42b8397360d318edf3093b20b2b102207d76730e1bPuneet Lallimport com.android.camera.one.v2.camera2proxy.AndroidImageReaderProxy;
4312f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
4412f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.camera2proxy.CameraDeviceProxy;
4512f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.camera2proxy.CameraDeviceRequestBuilderFactory;
46b8397360d318edf3093b20b2b102207d76730e1bPuneet Lallimport com.android.camera.one.v2.camera2proxy.ImageReaderProxy;
474961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lallimport com.android.camera.one.v2.camera2proxy.TotalCaptureResultProxy;
4812f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.commands.CameraCommandExecutor;
495f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.commands.ZslPreviewCommandFactory;
50d8463954727c9f8b688e69476439830cadb7b45aPuneet Lallimport com.android.camera.one.v2.common.BasicCameraFactory;
5112f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.common.SimpleCaptureStream;
5212f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.core.FrameServer;
5312f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.core.FrameServerFactory;
546a4a38d2320ab4e840cf4ad2ffb9714b0d7c1539Paul Rohdeimport com.android.camera.one.v2.core.RequestTemplate;
5566b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lallimport com.android.camera.one.v2.core.ResponseListener;
563c2c50c761de241085c81886b21575cfdec169b8Puneet Lallimport com.android.camera.one.v2.core.ResponseListeners;
573bc38870104d065beb667f2c1274efea26fbc3afPaul Rohdeimport com.android.camera.one.v2.errorhandling.FramerateJankDetector;
5866b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lallimport com.android.camera.one.v2.errorhandling.RepeatFailureHandlerComponent;
59b8397360d318edf3093b20b2b102207d76730e1bPuneet Lallimport com.android.camera.one.v2.imagesaver.ImageSaver;
6012f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.initialization.CameraStarter;
6112f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.initialization.InitializedOneCameraFactory;
6212f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.photo.ZslPictureTakerFactory;
6312f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.one.v2.sharedimagereader.ZslSharedImageReaderFactory;
649b2e78294a9dc91e871b8363e521250efbc3a20aAndy Huibersimport com.android.camera.stats.UsageStatistics;
65a1a76c8ae8a0c6f0ffca427758c771ee77af2c59Paul Rohdeimport com.android.camera.util.AndroidContext;
66593a03b147a0388530cc63ca83e23fea6107693fI-Jong Linimport com.android.camera.util.ApiHelper;
67a1a76c8ae8a0c6f0ffca427758c771ee77af2c59Paul Rohdeimport com.android.camera.util.GservicesHelper;
68270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lallimport com.android.camera.util.Provider;
6912f608f3d2089439a108788a1908941eea4277b9Puneet Lallimport com.android.camera.util.Size;
7081308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lallimport com.google.common.base.Supplier;
7112f608f3d2089439a108788a1908941eea4277b9Puneet Lall
7248fbf15e2c8806fc518f4c881ab17b1b548887d9Puneet Lallimport java.util.ArrayList;
7363204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lallimport java.util.Arrays;
7448fbf15e2c8806fc518f4c881ab17b1b548887d9Puneet Lallimport java.util.List;
75270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lallimport java.util.concurrent.ExecutorService;
7648fbf15e2c8806fc518f4c881ab17b1b548887d9Puneet Lallimport java.util.concurrent.Executors;
7748fbf15e2c8806fc518f4c881ab17b1b548887d9Puneet Lall
785f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde@TargetApi(VERSION_CODES.LOLLIPOP)
79d8463954727c9f8b688e69476439830cadb7b45aPuneet Lallpublic class ZslOneCameraFactory implements OneCameraFactory {
801e123ea83881996b6c5ac3e29702050cc42d43adPaul Rohde    private static Tag TAG = new Tag("ZslOneCamFactory");
811e123ea83881996b6c5ac3e29702050cc42d43adPaul Rohde
82b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall    private final Logger mLogger;
83d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall    private final int mImageFormat;
84d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall    private final int mMaxImageCount;
8536a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall    private final int maxRingBufferSize;
8612f608f3d2089439a108788a1908941eea4277b9Puneet Lall
87d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall    public ZslOneCameraFactory(int imageFormat, int maxImageCount) {
88d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        mImageFormat = imageFormat;
89d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        mMaxImageCount = maxImageCount;
901e123ea83881996b6c5ac3e29702050cc42d43adPaul Rohde        mLogger = Loggers.tagFactory().create(TAG);
9136a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall
9236a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // Determines the maximum size of the ZSL ring-buffer.
9336a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // Note that this is *different* from mMaxImageCount.
9436a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // mMaxImageCount determines the size of the ImageReader used for large
9536a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // (typically YUV) images to be saved. It is correlated with the total
9636a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // number of in-progress captures which can simultaneously occur by
9736a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // buffering captured images.
9836a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // maxRingBufferSize determines the maximum size of the ring-buffer
9936a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // (which uses a subset of the capacity of the ImageReader). This is
10036a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // correlated to the maximum amount of look-back for zero-shutter-lag
10136a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // photography. If this is greater than mMaxImageCount - 2, then it
10236a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // places no additional constraints on ring-buffer size. That is,
10336a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // the ring-buffer will expand to fill the entire capacity of the
10436a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // ImageReader whenever possible.
10536a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall
10636a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // A value of 1 here is adequate for single-frame ZSL capture, but
10736a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // *must* be increased to support multi-frame burst capture with
10836a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        // zero-shutter-lag.
10936a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall        maxRingBufferSize = 1;
110d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall    }
11112f608f3d2089439a108788a1908941eea4277b9Puneet Lall
112593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin    /**
113593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * Slows down the requested camera frame for Nexus 5 back camera issue. This
114593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * hack is for the Back Camera for Nexus 5. Requesting on full YUV frames at
115593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * 30 fps causes the video preview to deliver frames out of order, mostly
116593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * likely due to the overloading of the ISP, and/or image bandwith. The
117593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * short-term solution is to back off the frame rate to unadvertised, valid
1189a034a1119fbba2fa82362de74dcb671d2ce6c19I-Jong Lin     * frame rate of 28 fps. The long-term solution is to advertise this [7,28]
119593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * frame rate range in the HAL and get buy-in from the manufacturer to
120593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * support and CTS this feature. Then framerate process can occur in more
121593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * integrated manner. The tracking bug for this issue is b/18950682.
122593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     *
123593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     * @param requestTemplate Request template that will be applied to the
124593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     *            current camera device
125593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin     */
126593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin    private void applyNexus5BackCameraFrameRateWorkaround(RequestTemplate requestTemplate) {
127b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall        Range<Integer> frameRateBackOff = new Range<>(7, 28);
1286c3a702472798d446049bd6241851f3ae8775b57Puneet Lall        mLogger.v("Applying Nexus5 specific framerate backoff of " + frameRateBackOff);
129593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin        requestTemplate.setParam(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, frameRateBackOff);
130593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin    }
131593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin
132d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall    @Override
133d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall    public OneCamera createOneCamera(final CameraDeviceProxy device,
134d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall            final OneCameraCharacteristics characteristics,
1358f51086c8177056345de996963515c4bd3415254Sascha Haeberling            CaptureSupportLevel featureConfig,
13678276fbe6c30265d5e52df9ececb275ce898e684I-Jong Lin            final MainThread mainThread,
13766b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall            Size pictureSize,
13866b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall            final ImageSaver.Builder imageSaverBuilder,
139b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            final Observable<OneCamera.PhotoCaptureParameters.Flash> flashSetting,
140b6c4a314d0a0a185e6d987298ef9b7f4db8a6a2fSenpo Hu            final Observable<Integer> exposureSetting,
1410db8a2fd5cc02753d42f34a1c858b980c6c277bbPaul Rohde            final Observable<Boolean> hdrSceneSetting,
14266b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall            final BurstFacade burstFacade,
14366b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall            final FatalErrorHandler fatalErrorHandler) {
14463204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall        final Lifetime lifetime = new Lifetime();
145b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall
146b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall        final ImageReaderProxy imageReader = new CloseWhenDoneImageReader(
1471738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall                new LoggingImageReader(AndroidImageReaderProxy.newInstance(
148b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall                        pictureSize.getWidth(), pictureSize.getHeight(),
1491738db31add0aea5a6a6f2c137ca6fc476a10237Puneet Lall                        mImageFormat, mMaxImageCount), Loggers.tagFactory()));
15012f608f3d2089439a108788a1908941eea4277b9Puneet Lall
151b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall        lifetime.add(imageReader);
152b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall        lifetime.add(device);
15312f608f3d2089439a108788a1908941eea4277b9Puneet Lall
15412f608f3d2089439a108788a1908941eea4277b9Puneet Lall        List<Surface> outputSurfaces = new ArrayList<>();
15512f608f3d2089439a108788a1908941eea4277b9Puneet Lall        outputSurfaces.add(imageReader.getSurface());
156b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        if (burstFacade.getInputSurface() != null) {
157b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            outputSurfaces.add(burstFacade.getInputSurface());
158b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        }
15912f608f3d2089439a108788a1908941eea4277b9Puneet Lall
160d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        /**
161d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall         * Finishes constructing the camera when prerequisites, e.g. the preview
162d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall         * stream and capture session, are ready.
163d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall         */
164d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        CameraStarter cameraStarter = new CameraStarter() {
165d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall            @Override
166d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall            public CameraControls startCamera(Lifetime cameraLifetime,
167d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                    CameraCaptureSessionProxy cameraCaptureSession,
168d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                    Surface previewSurface,
169d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                    Observable<Float> zoomState,
1704961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                    Updatable<TotalCaptureResultProxy> metadataCallback,
17181308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                    Updatable<Boolean> readyStateCallback) {
172d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                // Create the FrameServer from the CaptureSession.
17363204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                FrameServerFactory frameServerComponent = new FrameServerFactory(new Lifetime
17463204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                        (cameraLifetime), cameraCaptureSession, new HandlerFactory());
17563204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall
17663204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                FrameServer frameServer = frameServerComponent.provideFrameServer();
17763204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                FrameServer ephemeralFrameServer = frameServerComponent
17863204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                        .provideEphemeralFrameServer();
17963204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall
18063204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                // Create the shared image reader.
18163204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                ZslSharedImageReaderFactory sharedImageReaderFactory =
18263204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                        new ZslSharedImageReaderFactory(new Lifetime(cameraLifetime),
18336a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall                                imageReader, new HandlerFactory(), maxRingBufferSize);
184d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
185270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                CameraCommandExecutor cameraCommandExecutor = new CameraCommandExecutor(
186270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                        Loggers.tagFactory(),
187270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                        new Provider<ExecutorService>() {
188270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                            @Override
189270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                            public ExecutorService get() {
190c44b7c47dbb8f53a6401285c4ca9218326d21a7ePuneet Lall                                // Use a dynamically-expanding thread pool to
191c44b7c47dbb8f53a6401285c4ca9218326d21a7ePuneet Lall                                // allow any number of commands to execute
192c44b7c47dbb8f53a6401285c4ca9218326d21a7ePuneet Lall                                // simultaneously.
193ccb0c17a104801a994c901d1c89c9d99005782edPuneet Lall                                return Executors.newCachedThreadPool();
194270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                            }
195270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                        });
196d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
197d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                // Create the request builder used by all camera operations.
198d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                // Streams, ResponseListeners, and Parameters added to
199d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                // this will be applied to *all* requests sent to the camera.
2007e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                RequestTemplate rootTemplate = new RequestTemplate(
2017e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                        new CameraDeviceRequestBuilderFactory(device));
2027e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                rootTemplate.addResponseListener(sharedImageReaderFactory
2037e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                        .provideGlobalResponseListener());
2047e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                rootTemplate.addResponseListener(ResponseListeners
2057e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                        .forFinalMetadata(metadataCallback));
2067e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin
2077e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                // Create the request builder for the preview warmup in order to workaround
2087e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                // the face detection failure. This is a work around of the HAL face detection
2097e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                // failure in b/20724126.
2107e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                RequestTemplate previewWarmupTemplate = new RequestTemplate(rootTemplate);
2117e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                previewWarmupTemplate.addStream(new SimpleCaptureStream(previewSurface));
2127e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin
2137e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                // Create the request builder for the ZSL stream
2147e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                RequestTemplate zslTemplate = new RequestTemplate(rootTemplate);
215ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                zslTemplate.addStream(sharedImageReaderFactory.provideZSLStream());
216d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
2175f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                // Create the request builder that will be used by most camera
2185f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                // operations.
2195f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                RequestTemplate zslAndPreviewTemplate = new RequestTemplate(zslTemplate);
2205f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                zslAndPreviewTemplate.addStream(new SimpleCaptureStream(previewSurface));
2215f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
222593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin                boolean isBackCamera = characteristics.getCameraDirection() ==
223593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin                        OneCamera.Facing.BACK;
224593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin
225593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin                if (isBackCamera && ApiHelper.IS_NEXUS_5) {
2265f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                    applyNexus5BackCameraFrameRateWorkaround(zslTemplate);
227593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin                }
228593a03b147a0388530cc63ca83e23fea6107693fI-Jong Lin
2294961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                // Create basic functionality (zoom, AE, AF).
2304961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                BasicCameraFactory basicCameraFactory = new BasicCameraFactory(
231ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        new Lifetime(cameraLifetime),
232ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        characteristics,
233ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        ephemeralFrameServer,
2345f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                        zslAndPreviewTemplate,
235ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        cameraCommandExecutor,
2367e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                        new ZslPreviewCommandFactory(ephemeralFrameServer,
2377e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                                previewWarmupTemplate,
2387e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                                zslTemplate),
239ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        flashSetting,
240ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        exposureSetting,
241ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        zoomState,
242ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        hdrSceneSetting,
243ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
244d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
24563204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                lifetime.add(cameraCommandExecutor);
246d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
24763204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                // Create the picture-taker.
2485ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lall                ZslPictureTakerFactory pictureTakerFactory = ZslPictureTakerFactory.create(
2495ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lall                        Loggers.tagFactory(),
250386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall                        mainThread,
251270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                        cameraCommandExecutor,
2524961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                        imageSaverBuilder,
2534961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                        frameServer,
2544961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                        basicCameraFactory.provideMeteredZoomedRequestBuilder(),
2554961ad31d9a877e3a68566fb5d4b33b7f79ce44ePuneet Lall                        sharedImageReaderFactory.provideSharedImageReader(),
25663204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                        sharedImageReaderFactory.provideZSLStream(),
2575ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lall                        sharedImageReaderFactory.provideMetadataPool(),
2585ca7d2642881f3cf06adb2532e0d5950524a34f4Puneet Lall                        flashSetting,
2595f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                        zslAndPreviewTemplate);
260ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde
261ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                BurstTaker burstTaker = new BurstTakerImpl(cameraCommandExecutor,
262ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        frameServer,
263259ef720650f3d4e77dd381167ed12cdfd489403Shashi Shekhar                        basicCameraFactory.provideMeteredZoomedRequestBuilder(),
264259ef720650f3d4e77dd381167ed12cdfd489403Shashi Shekhar                        sharedImageReaderFactory.provideSharedImageReader(),
265ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        burstFacade.getInputSurface(),
266ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                        basicCameraFactory.providePreviewUpdater(),
26766b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall                        // ImageReader#acquireLatestImage() requires two images
26866b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall                        // as the margin so
26966b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall                        // specify that as the maximum number of images that can
27066b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall                        // be used by burst.
271b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                        mMaxImageCount - 2);
272b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                burstFacade.setBurstTaker(burstTaker);
273d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
274270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                if (isBackCamera && ApiHelper.IS_NEXUS_5) {
275270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                    // Workaround for bug: 19061883
27666b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall                    ResponseListener failureDetector = RepeatFailureHandlerComponent.create(
27766b942a3d20aac65454961ef2bc219ca560b9fbaPuneet Lall                            Loggers.tagFactory(),
278ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                            fatalErrorHandler,
279ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                            cameraCaptureSession,
280ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                            cameraCommandExecutor,
281ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                            basicCameraFactory.providePreviewUpdater(),
282ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                            UsageStatistics.instance(),
283ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                            10 /* consecutiveFailureThreshold */).provideResponseListener();
2845f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                    zslTemplate.addResponseListener(failureDetector);
285270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall                }
286d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
287a1a76c8ae8a0c6f0ffca427758c771ee77af2c59Paul Rohde                if (GservicesHelper.isJankStatisticsEnabled(AndroidContext.instance().get()
28836a1ad23bead41193e22442d3196e93a01ec7fe6Puneet Lall                        .getContentResolver())) {
2895f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                    // Don't add jank detection unless the preview is running.
2905f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                    zslAndPreviewTemplate.addResponseListener(
291ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                          new FramerateJankDetector(Loggers.tagFactory(),
292ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                                UsageStatistics.instance()));
2933bc38870104d065beb667f2c1274efea26fbc3afPaul Rohde                }
2943bc38870104d065beb667f2c1274efea26fbc3afPaul Rohde
29581308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                final Observable<Integer> availableImageCount = sharedImageReaderFactory
29681308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                        .provideAvailableImageCount();
29781308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                final Observable<Boolean> frameServerAvailability = frameServerComponent
29881308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                        .provideReadyState();
29981308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                Observable<Boolean> readyObservable = Observables.transform(
30081308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                        Arrays.asList(availableImageCount, frameServerAvailability),
30181308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                        new Supplier<Boolean>() {
30263204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                            @Override
30381308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                            public Boolean get() {
30481308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                                boolean atLeastOneImageAvailable = availableImageCount.get() >= 1;
30581308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                                boolean frameServerAvailable = frameServerAvailability.get();
30681308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                                return atLeastOneImageAvailable && frameServerAvailable;
30763204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                            }
30863204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall                        });
30963204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall
31081308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                lifetime.add(Observables.addThreadSafeCallback(readyObservable,
31181308a22b0f64c6667f6c23adee9da520415bcb6Puneet Lall                        readyStateCallback));
31263204dc989dbd0eba56f65086fde0ebe29ed6bdbPuneet Lall
313ffae1b53110ddae98b810bdb9a5c9dc210d96551Paul Rohde                basicCameraFactory.providePreviewUpdater().run();
314270990a7e3fcd1cf71b652c9ad1cc46598ddf4b3Puneet Lall
315d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                return new CameraControls(
316d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                        pictureTakerFactory.providePictureTaker(),
317d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall                        basicCameraFactory.provideManualAutoFocus());
318d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall            }
319d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        };
320d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall
321d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        float maxZoom = characteristics.getAvailableMaxDigitalZoom();
322d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        List<Size> supportedPreviewSizes = characteristics.getSupportedPreviewSizes();
323d8463954727c9f8b688e69476439830cadb7b45aPuneet Lall        OneCamera.Facing direction = characteristics.getCameraDirection();
324b8397360d318edf3093b20b2b102207d76730e1bPuneet Lall        return new InitializedOneCameraFactory(lifetime, cameraStarter, device,
325386c5b885b99f67f9c0a7380f4be153f28333089Puneet Lall                outputSurfaces, mainThread, new HandlerFactory(), maxZoom,
326aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde                supportedPreviewSizes, characteristics.getLensFocusRange(),
327aca904e29aea542b6e6a4fcc837759a57a270a49Paul Rohde                direction).provideOneCamera();
32812f608f3d2089439a108788a1908941eea4277b9Puneet Lall    }
32912f608f3d2089439a108788a1908941eea4277b9Puneet Lall}
330