15f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde/*
25f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * Copyright (C) 2015 The Android Open Source Project
35f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde *
45f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * Licensed under the Apache License, Version 2.0 (the "License");
55f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * you may not use this file except in compliance with the License.
65f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * You may obtain a copy of the License at
75f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde *
85f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde *      http://www.apache.org/licenses/LICENSE-2.0
95f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde *
105f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * Unless required by applicable law or agreed to in writing, software
115f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * distributed under the License is distributed on an "AS IS" BASIS,
125f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * See the License for the specific language governing permissions and
145f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * limitations under the License.
155f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde */
165f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
175f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdepackage com.android.camera.one.v2.commands;
185f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
195f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport android.hardware.camera2.CameraAccessException;
205f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
215f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException;
225f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.core.FrameServer;
235f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.core.FrameServer.RequestType;
245f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.core.Request;
255f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.core.RequestBuilder;
265f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport com.android.camera.one.v2.core.ResourceAcquisitionFailedException;
277e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jinimport com.android.camera.util.ApiHelper;
285f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
295f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport java.util.ArrayList;
305f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport java.util.Arrays;
315f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport java.util.List;
325f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdeimport java.util.concurrent.atomic.AtomicBoolean;
335f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
345f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde/**
355f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * Delegate the first run of a frameserver command to a different
365f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde * camera command than subsequent executions.
375f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde */
385f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohdepublic class ZslPreviewCommand implements CameraCommand {
395f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final FrameServer mFrameServer;
407e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin    private final RequestBuilder.Factory mPreviewWarmupRequestBuilder;
417e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin    private final int mPreviewWarmupRequestType;
425f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final RequestBuilder.Factory mZslRequestBuilder;
435f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final int mZslRequestType;
445f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final RequestBuilder.Factory mZslAndPreviewRequestBuilder;
455f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final int mZslAndPreviewRequestType;
465f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final int mWarmupBurstSize;
475f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private final AtomicBoolean mIsFirstRun;
485f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
495f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    /**
505f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde     * Constructs a Preview. Note that it is the responsiblity of the
515f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde     * {@link RequestBuilder.Factory} to attach the relevant
525f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde     * {@link com.android.camera.one.v2.core.CaptureStream}s, such as the
535f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde     * viewfinder surface.
545f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde     */
555f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    public ZslPreviewCommand(FrameServer frameServer,
567e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin          RequestBuilder.Factory previewWarmupRequestBuilder,
577e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin          int previewWarmupRequestType,
585f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          RequestBuilder.Factory zslRequestBuilder,
595f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          int zslRequestType,
605f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          RequestBuilder.Factory zslAndPreviewRequestBuilder,
615f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          int zslAndPreviewRequestType,
625f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          int warmupBurstSize) {
635f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mFrameServer = frameServer;
647e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin        mPreviewWarmupRequestBuilder = previewWarmupRequestBuilder;
657e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin        mPreviewWarmupRequestType = previewWarmupRequestType;
665f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mZslRequestBuilder = zslRequestBuilder;
675f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mZslRequestType = zslRequestType;
685f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mZslAndPreviewRequestBuilder = zslAndPreviewRequestBuilder;
695f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mZslAndPreviewRequestType = zslAndPreviewRequestType;
705f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mWarmupBurstSize = warmupBurstSize;
715f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        mIsFirstRun = new AtomicBoolean(true);
725f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    }
735f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
745f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    public void run() throws InterruptedException, CameraAccessException,
755f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          CameraCaptureSessionClosedException, ResourceAcquisitionFailedException {
765f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        try (FrameServer.Session session = mFrameServer.createExclusiveSession()) {
775f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            if (mIsFirstRun.getAndSet(false)) {
787e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                if (ApiHelper.isLorLMr1() && ApiHelper.IS_NEXUS_6) {
797e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                    // This is the work around of the face detection failure in b/20724126.
807e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                    // We need to request a single preview frame followed by a burst of 5-frame ZSL
817e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                    // before requesting the repeating preview and ZSL requests. We do it only for
827e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                    // L, Nexus 6 and Haleakala.
837e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                    List<Request> previewWarming = createWarmupBurst(mPreviewWarmupRequestBuilder,
847e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                            mPreviewWarmupRequestType, 1);
857e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                    session.submitRequest(previewWarming, RequestType.NON_REPEATING);
867e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                }
877e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin
887e39f8b015985fc0e539e14c193286065b5e51d4Pengchong Jin                // Only run a warmup burst the first time this command is executed.
895f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                List<Request> zslWarmingBurst =
905f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                      createWarmupBurst(mZslRequestBuilder, mZslRequestType, mWarmupBurstSize);
915f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                session.submitRequest(zslWarmingBurst, RequestType.NON_REPEATING);
925f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            }
935f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
945f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            // Build the zsl + preview repeating request.
955f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            RequestBuilder zslAndPreviewRequest = mZslAndPreviewRequestBuilder.create(
965f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde                  mZslAndPreviewRequestType);
975f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            List<Request> zslAndPreviewRepeating = Arrays.asList(zslAndPreviewRequest.build());
985f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
995f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            // Submit the normal repeating request.
1005f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            session.submitRequest(zslAndPreviewRepeating, RequestType.REPEATING);
1015f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        }
1025f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    }
1035f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde
1045f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    private List<Request> createWarmupBurst(RequestBuilder.Factory builder, int type, int size)
1055f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde          throws CameraAccessException {
1065f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        RequestBuilder zslRequest = builder.create(type);
1075f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        Request zslWarmingRequest = zslRequest.build();
1085f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        List<Request> zslWarmingBurst = new ArrayList<>(size);
1095f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        for (int i = 0; i < size; i++) {
1105f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde            zslWarmingBurst.add(zslWarmingRequest);
1115f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        }
1125f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde        return zslWarmingBurst;
1135f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde    }
1145f1f618eb3df6b9a2f8554e97e8410467b642653Paul Rohde}
115