124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu/*
224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * Copyright (C) 2015 The Android Open Source Project
324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu *
424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * Licensed under the Apache License, Version 2.0 (the "License");
524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * you may not use this file except in compliance with the License.
624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * You may obtain a copy of the License at
724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu *
824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu *      http://www.apache.org/licenses/LICENSE-2.0
924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu *
1024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * Unless required by applicable law or agreed to in writing, software
1124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * distributed under the License is distributed on an "AS IS" BASIS,
1224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * See the License for the specific language governing permissions and
1424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * limitations under the License.
1524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu */
1624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
1724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hupackage com.android.camera.captureintent.state;
1824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
191d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport com.android.camera.CaptureModuleUtil;
2024be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.async.RefCountBase;
211d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnStartPreviewFailed;
221d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnStartPreviewSucceeded;
231d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnTextureViewLayoutChanged;
241d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventPause;
25d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceConstructed;
26d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceOpenedCamera;
27d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceOpenedCameraImpl;
28d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceSurfaceTexture;
29d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.EventHandler;
30d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.State;
31d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.StateImpl;
3224be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.debug.Log;
331d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.device.CameraId;
341d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport com.android.camera.exif.Rational;
3524be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.one.OneCamera;
361d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport com.android.camera.one.OneCameraAccessException;
378aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Huimport com.android.camera.one.OneCameraCaptureSetting;
3824be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.one.OneCameraCharacteristics;
3924be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.util.Size;
401d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.google.common.base.Optional;
4124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
421d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport java.util.List;
431d518e63212290741d66aaf34356bd3897bb609eSenpo Hu
441d518e63212290741d66aaf34356bd3897bb609eSenpo Hu/**
451d518e63212290741d66aaf34356bd3897bb609eSenpo Hu * Represents a state that the module is waiting for the preview video stream
461d518e63212290741d66aaf34356bd3897bb609eSenpo Hu * to be started.
471d518e63212290741d66aaf34356bd3897bb609eSenpo Hu */
48d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hupublic final class StateStartingPreview extends StateImpl {
49de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu    private static final Log.Tag TAG = new Log.Tag("StStartingPreview");
5024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
5124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceConstructed> mResourceConstructed;
5224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceSurfaceTexture> mResourceSurfaceTexture;
5324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceOpenedCamera> mResourceOpenedCamera;
5424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
5524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public static StateStartingPreview from(
56cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu            State previousState,
5724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceConstructed> resourceConstructed,
5824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture,
5924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            OneCamera camera,
608aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu            CameraId cameraId,
6124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            OneCamera.Facing cameraFacing,
6224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            OneCameraCharacteristics cameraCharacteristics,
638aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu            Size pictureSize,
648aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu            OneCameraCaptureSetting captureSetting) {
6580aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        return new StateStartingPreview(
66cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                previousState,
6780aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                resourceConstructed,
6880aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                resourceSurfaceTexture,
6980aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                camera,
701d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                cameraId,
7180aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                cameraFacing,
7280aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                cameraCharacteristics,
738aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu                pictureSize,
748aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu                captureSetting);
7524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
7624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
7724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private StateStartingPreview(
7824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            State previousState,
7924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceConstructed> resourceConstructed,
8024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture,
8180aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            OneCamera camera,
821d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            CameraId cameraId,
8380aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            OneCamera.Facing cameraFacing,
8480aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            OneCameraCharacteristics cameraCharacteristics,
858aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu            Size pictureSize,
868aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu            OneCameraCaptureSetting captureSetting) {
87d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        super(previousState);
8824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceConstructed = resourceConstructed;
8980aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mResourceConstructed.addRef();     // Will be balanced in onLeave().
9024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceSurfaceTexture = resourceSurfaceTexture;
9180aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mResourceSurfaceTexture.addRef();  // Will be balanced in onLeave().
92d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        mResourceOpenedCamera = ResourceOpenedCameraImpl.create(
938aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu                camera, cameraId, cameraFacing, cameraCharacteristics, pictureSize, captureSetting);
94d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        registerEventHandlers();
95d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    }
96d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
97d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    public void registerEventHandlers() {
98d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventPause. */
99d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventPause> pauseHandler = new EventHandler<EventPause>() {
100d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            @Override
101d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            public Optional<State> processEvent(EventPause event) {
102d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                return Optional.of((State) StateBackgroundWithSurfaceTexture.from(
103d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        StateStartingPreview.this,
104d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceConstructed,
105d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceSurfaceTexture));
106d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            }
107d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        };
108d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventPause.class, pauseHandler);
109d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
110d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnTextureViewLayoutChanged. */
111d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnTextureViewLayoutChanged> onTextureViewLayoutChangedHandler =
112d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnTextureViewLayoutChanged>() {
113d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
114d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnTextureViewLayoutChanged event) {
115d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceSurfaceTexture.get().setPreviewLayoutSize(event.getLayoutSize());
116d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
117d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
118d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
119d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnTextureViewLayoutChanged.class, onTextureViewLayoutChangedHandler);
120d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
121d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnStartPreviewSucceeded. */
122d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnStartPreviewSucceeded> onStartPreviewSucceededHandler =
123d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnStartPreviewSucceeded>() {
124d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
125d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnStartPreviewSucceeded event) {
126d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceConstructed.get().getMainThread().execute(new Runnable() {
127d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            @Override
128d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            public void run() {
129d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceConstructed.get().getModuleUI().onPreviewStarted();
130d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            }
131d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        });
132d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return Optional.of((State) StateReadyForCapture.from(
133d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                StateStartingPreview.this,
134d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceConstructed,
135d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceSurfaceTexture,
136d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceOpenedCamera));
137d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
138d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
139d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnStartPreviewSucceeded.class, onStartPreviewSucceededHandler);
140d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
141d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnStartPreviewFailed. */
142d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnStartPreviewFailed> onStartPreviewFailedHandler =
143d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnStartPreviewFailed>() {
144d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
145d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnStartPreviewFailed event) {
146d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        Log.e(TAG, "processOnPreviewSetupFailed");
147d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return Optional.of((State) StateFatal.from(
148d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                StateStartingPreview.this, mResourceConstructed));
149d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
150d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
151d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnStartPreviewFailed.class, onStartPreviewFailedHandler);
15224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
15324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
15424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
15524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public Optional<State> onEnter() {
1561d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        final Size previewSize;
1571d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        try {
1581d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            // Pick a preview size with the right aspect ratio.
1591d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            final List<Size> supportedPreviewSizes = mResourceOpenedCamera.get()
1601d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    .getCameraCharacteristics().getSupportedPreviewSizes();
1613ad9c9035f8be50f6b2ef8cac9943045f7cf8a74Sascha Haeberling            if (supportedPreviewSizes.isEmpty()) {
1623ad9c9035f8be50f6b2ef8cac9943045f7cf8a74Sascha Haeberling                return Optional.of((State) StateFatal.from(this, mResourceConstructed));
1633ad9c9035f8be50f6b2ef8cac9943045f7cf8a74Sascha Haeberling            }
1643ad9c9035f8be50f6b2ef8cac9943045f7cf8a74Sascha Haeberling
1651d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            final Rational pictureAspectRatio =
1661d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    mResourceConstructed.get().getResolutionSetting().getPictureAspectRatio(
1671d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                          mResourceOpenedCamera.get().getCameraId(),
1681d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                          mResourceOpenedCamera.get().getCameraFacing());
1691d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            previewSize = CaptureModuleUtil.getOptimalPreviewSize(
1701d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    supportedPreviewSizes.toArray(new Size[(supportedPreviewSizes.size())]),
1711d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    pictureAspectRatio.toDouble(),
1721d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    null);
1731d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            if (previewSize == null) {
174698e271d2b263778bfa73d1e67d6e2cd2783c89ezafir                // TODO: Try to avoid entering StateFatal by seeing if there is
175698e271d2b263778bfa73d1e67d6e2cd2783c89ezafir                // another way to get the correct preview size.
1761d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                return Optional.of((State) StateFatal.from(this, mResourceConstructed));
1771d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            }
1781d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        } catch (OneCameraAccessException ex) {
1791d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            return Optional.of((State) StateFatal.from(this, mResourceConstructed));
1801d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        }
181de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu
182de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // Must do this before calling ResourceOpenedCamera.startPreview()
183de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // since SurfaceTexture.setDefaultBufferSize() needs to be called
184de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // before starting preview. Otherwise the size of preview video stream
185de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // will be wrong.
186de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        mResourceSurfaceTexture.get().setPreviewSize(previewSize);
187de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu
188d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        OneCamera.CaptureReadyCallback captureReadyCallback =
189d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new OneCamera.CaptureReadyCallback() {
190d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
191d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public void onSetupFailed() {
192d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        getStateMachine().processEvent(new EventOnStartPreviewFailed());
193d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
194d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
195d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
196d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public void onReadyForCapture() {
197d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        getStateMachine().processEvent(new EventOnStartPreviewSucceeded());
198d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
199d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
200d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
2018b4309b20d64b15bc49d5cdc891d09208f009f06Senpo Hu        // Start preview right away. Don't dispatch it on other threads or it
2028b4309b20d64b15bc49d5cdc891d09208f009f06Senpo Hu        // will cause race condition. b/19522251.
2038b4309b20d64b15bc49d5cdc891d09208f009f06Senpo Hu        mResourceOpenedCamera.get().startPreview(
204d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                mResourceSurfaceTexture.get().createPreviewSurface(), captureReadyCallback);
20524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return Optional.absent();
20624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
20724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
20824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
20924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onLeave() {
21024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceConstructed.close();
21124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceSurfaceTexture.close();
21224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceOpenedCamera.close();
21324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
21424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu}
215