1 /*
2  * Copyright (C) 2015 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.commands;
18 
19 import android.hardware.camera2.CameraAccessException;
20 
21 import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionClosedException;
22 import com.android.camera.one.v2.core.FrameServer;
23 import com.android.camera.one.v2.core.FrameServer.RequestType;
24 import com.android.camera.one.v2.core.Request;
25 import com.android.camera.one.v2.core.RequestBuilder;
26 import com.android.camera.one.v2.core.ResourceAcquisitionFailedException;
27 import com.android.camera.util.ApiHelper;
28 
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
32 import java.util.concurrent.atomic.AtomicBoolean;
33 
34 /**
35  * Delegate the first run of a frameserver command to a different
36  * camera command than subsequent executions.
37  */
38 public class ZslPreviewCommand implements CameraCommand {
39     private final FrameServer mFrameServer;
40     private final RequestBuilder.Factory mPreviewWarmupRequestBuilder;
41     private final int mPreviewWarmupRequestType;
42     private final RequestBuilder.Factory mZslRequestBuilder;
43     private final int mZslRequestType;
44     private final RequestBuilder.Factory mZslAndPreviewRequestBuilder;
45     private final int mZslAndPreviewRequestType;
46     private final int mWarmupBurstSize;
47     private final AtomicBoolean mIsFirstRun;
48 
49     /**
50      * Constructs a Preview. Note that it is the responsiblity of the
51      * {@link RequestBuilder.Factory} to attach the relevant
52      * {@link com.android.camera.one.v2.core.CaptureStream}s, such as the
53      * viewfinder surface.
54      */
ZslPreviewCommand(FrameServer frameServer, RequestBuilder.Factory previewWarmupRequestBuilder, int previewWarmupRequestType, RequestBuilder.Factory zslRequestBuilder, int zslRequestType, RequestBuilder.Factory zslAndPreviewRequestBuilder, int zslAndPreviewRequestType, int warmupBurstSize)55     public ZslPreviewCommand(FrameServer frameServer,
56           RequestBuilder.Factory previewWarmupRequestBuilder,
57           int previewWarmupRequestType,
58           RequestBuilder.Factory zslRequestBuilder,
59           int zslRequestType,
60           RequestBuilder.Factory zslAndPreviewRequestBuilder,
61           int zslAndPreviewRequestType,
62           int warmupBurstSize) {
63         mFrameServer = frameServer;
64         mPreviewWarmupRequestBuilder = previewWarmupRequestBuilder;
65         mPreviewWarmupRequestType = previewWarmupRequestType;
66         mZslRequestBuilder = zslRequestBuilder;
67         mZslRequestType = zslRequestType;
68         mZslAndPreviewRequestBuilder = zslAndPreviewRequestBuilder;
69         mZslAndPreviewRequestType = zslAndPreviewRequestType;
70         mWarmupBurstSize = warmupBurstSize;
71         mIsFirstRun = new AtomicBoolean(true);
72     }
73 
run()74     public void run() throws InterruptedException, CameraAccessException,
75           CameraCaptureSessionClosedException, ResourceAcquisitionFailedException {
76         try (FrameServer.Session session = mFrameServer.createExclusiveSession()) {
77             if (mIsFirstRun.getAndSet(false)) {
78                 if (ApiHelper.isLorLMr1() && ApiHelper.IS_NEXUS_6) {
79                     // This is the work around of the face detection failure in b/20724126.
80                     // We need to request a single preview frame followed by a burst of 5-frame ZSL
81                     // before requesting the repeating preview and ZSL requests. We do it only for
82                     // L, Nexus 6 and Haleakala.
83                     List<Request> previewWarming = createWarmupBurst(mPreviewWarmupRequestBuilder,
84                             mPreviewWarmupRequestType, 1);
85                     session.submitRequest(previewWarming, RequestType.NON_REPEATING);
86                 }
87 
88                 // Only run a warmup burst the first time this command is executed.
89                 List<Request> zslWarmingBurst =
90                       createWarmupBurst(mZslRequestBuilder, mZslRequestType, mWarmupBurstSize);
91                 session.submitRequest(zslWarmingBurst, RequestType.NON_REPEATING);
92             }
93 
94             // Build the zsl + preview repeating request.
95             RequestBuilder zslAndPreviewRequest = mZslAndPreviewRequestBuilder.create(
96                   mZslAndPreviewRequestType);
97             List<Request> zslAndPreviewRepeating = Arrays.asList(zslAndPreviewRequest.build());
98 
99             // Submit the normal repeating request.
100             session.submitRequest(zslAndPreviewRepeating, RequestType.REPEATING);
101         }
102     }
103 
createWarmupBurst(RequestBuilder.Factory builder, int type, int size)104     private List<Request> createWarmupBurst(RequestBuilder.Factory builder, int type, int size)
105           throws CameraAccessException {
106         RequestBuilder zslRequest = builder.create(type);
107         Request zslWarmingRequest = zslRequest.build();
108         List<Request> zslWarmingBurst = new ArrayList<>(size);
109         for (int i = 0; i < size; i++) {
110             zslWarmingBurst.add(zslWarmingRequest);
111         }
112         return zslWarmingBurst;
113     }
114 }
115