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
17package com.android.camera.one.v2.initialization;
18
19import android.view.Surface;
20
21import com.android.camera.one.OneCamera;
22import com.android.camera.one.v2.camera2proxy.CameraCaptureSessionProxy;
23import com.android.camera.util.ApiHelper;
24import com.google.common.util.concurrent.AsyncFunction;
25import com.google.common.util.concurrent.Futures;
26import com.google.common.util.concurrent.ListenableFuture;
27
28import java.util.ArrayList;
29import java.util.List;
30
31/**
32 * When the preview surface is available, creates a capture session, and then
33 * notifies the listener when the session is available.
34 */
35class PreviewStarter {
36    public interface CameraCaptureSessionCreatedListener {
37        public void onCameraCaptureSessionCreated(CameraCaptureSessionProxy session, Surface
38                previewSurface);
39    }
40
41    private final List<Surface> mOutputSurfaces;
42    private final CaptureSessionCreator mCaptureSessionCreator;
43    private final CameraCaptureSessionCreatedListener mSessionListener;
44
45    /**
46     * @param outputSurfaces The set of output surfaces (except for the preview
47     *            surface) to use.
48     * @param captureSessionCreator
49     * @param sessionListener A callback to be invoked when the capture session
50     *            has been created. It is executed on threadPoolExecutor.
51     */
52    public PreviewStarter(List<Surface> outputSurfaces,
53            CaptureSessionCreator captureSessionCreator,
54            CameraCaptureSessionCreatedListener sessionListener) {
55        mOutputSurfaces = outputSurfaces;
56        mCaptureSessionCreator = captureSessionCreator;
57        mSessionListener = sessionListener;
58    }
59
60    /**
61     * See {@link OneCamera#startPreview}.
62     *
63     * @param surface The preview surface to use.
64     */
65    public ListenableFuture<Void> startPreview(final Surface surface) {
66        // When we have the preview surface, start the capture session.
67        List<Surface> surfaceList = new ArrayList<>();
68
69        // Workaround of the face detection failure on Nexus 5 and L. (b/21039466)
70        // Need to create a capture session with the single preview stream first
71        // to lock it as the first stream. Then resend the another session with preview
72        // and JPEG stream.
73        if (ApiHelper.isLorLMr1() && ApiHelper.IS_NEXUS_5) {
74            surfaceList.add(surface);
75            mCaptureSessionCreator.createCaptureSession(surfaceList);
76            surfaceList.addAll(mOutputSurfaces);
77        } else {
78            surfaceList.addAll(mOutputSurfaces);
79            surfaceList.add(surface);
80        }
81
82        final ListenableFuture<CameraCaptureSessionProxy> sessionFuture =
83                mCaptureSessionCreator.createCaptureSession(surfaceList);
84
85        return Futures.transform(sessionFuture,
86                new AsyncFunction<CameraCaptureSessionProxy, Void>() {
87                    @Override
88                    public ListenableFuture<Void> apply(
89                            CameraCaptureSessionProxy captureSession) throws Exception {
90                        mSessionListener.onCameraCaptureSessionCreated(captureSession, surface);
91                        return Futures.immediateFuture(null);
92                    }
93                });
94    }
95}
96