StateStartingPreview.java revision cc6139467c1c9545de1f098d938409e182c9b7ad
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
1924be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.google.common.base.Optional;
2024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
211d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport com.android.camera.CaptureModuleUtil;
2224be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.async.RefCountBase;
23d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceConstructed;
24d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceOpenedCamera;
25d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceOpenedCameraImpl;
26d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.resource.ResourceSurfaceTexture;
27d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.EventHandler;
281b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Huimport com.android.camera.captureintent.event.EventOnStartPreviewFailed;
291b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Huimport com.android.camera.captureintent.event.EventOnStartPreviewSucceeded;
30d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventOnTextureViewLayoutChanged;
31d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventPause;
32d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.State;
33d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.StateImpl;
3424be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.debug.Log;
351d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport com.android.camera.exif.Rational;
3624be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.one.OneCamera;
371d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport com.android.camera.one.OneCameraAccessException;
3824be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.one.OneCameraCharacteristics;
3924be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.util.Size;
4024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
411d518e63212290741d66aaf34356bd3897bb609eSenpo Huimport java.util.List;
421d518e63212290741d66aaf34356bd3897bb609eSenpo Hu
431d518e63212290741d66aaf34356bd3897bb609eSenpo Hu/**
441d518e63212290741d66aaf34356bd3897bb609eSenpo Hu * Represents a state that the module is waiting for the preview video stream
451d518e63212290741d66aaf34356bd3897bb609eSenpo Hu * to be started.
461d518e63212290741d66aaf34356bd3897bb609eSenpo Hu */
47d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hupublic final class StateStartingPreview extends StateImpl {
48de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu    private static final Log.Tag TAG = new Log.Tag("StStartingPreview");
4924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
5024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceConstructed> mResourceConstructed;
5124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceSurfaceTexture> mResourceSurfaceTexture;
5224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceOpenedCamera> mResourceOpenedCamera;
5324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
5424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public static StateStartingPreview from(
55cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu            State previousState,
5624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceConstructed> resourceConstructed,
5724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture,
5824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            OneCamera camera,
5924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            OneCamera.Facing cameraFacing,
6024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            OneCameraCharacteristics cameraCharacteristics,
611b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            Size pictureSize) {
6280aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        return new StateStartingPreview(
63cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                previousState,
6480aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                resourceConstructed,
6580aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                resourceSurfaceTexture,
6680aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                camera,
6780aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                cameraFacing,
6880aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu                cameraCharacteristics,
691b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                pictureSize);
7024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
7124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
7224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private StateStartingPreview(
7324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            State previousState,
7424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceConstructed> resourceConstructed,
7524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture,
7680aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            OneCamera camera,
7780aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            OneCamera.Facing cameraFacing,
7880aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            OneCameraCharacteristics cameraCharacteristics,
791b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            Size pictureSize) {
80d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        super(previousState);
8124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceConstructed = resourceConstructed;
8280aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mResourceConstructed.addRef();     // Will be balanced in onLeave().
8324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceSurfaceTexture = resourceSurfaceTexture;
8480aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mResourceSurfaceTexture.addRef();  // Will be balanced in onLeave().
85d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        mResourceOpenedCamera = ResourceOpenedCameraImpl.create(
861b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                camera, cameraFacing, cameraCharacteristics, pictureSize);
87d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        registerEventHandlers();
88d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    }
89d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
90d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    public void registerEventHandlers() {
91d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventPause. */
92d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventPause> pauseHandler = new EventHandler<EventPause>() {
93d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            @Override
94d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            public Optional<State> processEvent(EventPause event) {
95d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                return Optional.of((State) StateBackgroundWithSurfaceTexture.from(
96d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        StateStartingPreview.this,
97d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceConstructed,
98d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceSurfaceTexture));
99d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            }
100d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        };
101d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventPause.class, pauseHandler);
102d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
103d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnTextureViewLayoutChanged. */
104d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnTextureViewLayoutChanged> onTextureViewLayoutChangedHandler =
105d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnTextureViewLayoutChanged>() {
106d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
107d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnTextureViewLayoutChanged event) {
108d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceSurfaceTexture.get().setPreviewLayoutSize(event.getLayoutSize());
109d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
110d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
111d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
112d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnTextureViewLayoutChanged.class, onTextureViewLayoutChangedHandler);
113d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
114d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnStartPreviewSucceeded. */
115d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnStartPreviewSucceeded> onStartPreviewSucceededHandler =
116d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnStartPreviewSucceeded>() {
117d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
118d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnStartPreviewSucceeded event) {
119d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceConstructed.get().getMainThread().execute(new Runnable() {
120d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            @Override
121d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            public void run() {
122d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceConstructed.get().getModuleUI().onPreviewStarted();
123d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            }
124d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        });
125d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return Optional.of((State) StateReadyForCapture.from(
126d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                StateStartingPreview.this,
127d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceConstructed,
128d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceSurfaceTexture,
129d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceOpenedCamera));
130d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
131d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
132d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnStartPreviewSucceeded.class, onStartPreviewSucceededHandler);
133d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
134d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnStartPreviewFailed. */
135d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnStartPreviewFailed> onStartPreviewFailedHandler =
136d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnStartPreviewFailed>() {
137d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
138d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnStartPreviewFailed event) {
139d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        Log.e(TAG, "processOnPreviewSetupFailed");
140d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return Optional.of((State) StateFatal.from(
141d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                StateStartingPreview.this, mResourceConstructed));
142d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
143d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
144d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnStartPreviewFailed.class, onStartPreviewFailedHandler);
14524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
14624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
14724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
14824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public Optional<State> onEnter() {
1491d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        final Size previewSize;
1501d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        try {
1511d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            // Pick a preview size with the right aspect ratio.
1521d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            final List<Size> supportedPreviewSizes = mResourceOpenedCamera.get()
1531d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    .getCameraCharacteristics().getSupportedPreviewSizes();
1541d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            final Rational pictureAspectRatio =
1551d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    mResourceConstructed.get().getResolutionSetting().getPictureAspectRatio(
1561d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                            mResourceOpenedCamera.get().getCameraFacing());
1571d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            previewSize = CaptureModuleUtil.getOptimalPreviewSize(
1581d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    supportedPreviewSizes.toArray(new Size[(supportedPreviewSizes.size())]),
1591d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    pictureAspectRatio.toDouble(),
1601d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                    null);
1611d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            if (previewSize == null) {
1621d518e63212290741d66aaf34356bd3897bb609eSenpo Hu                return Optional.of((State) StateFatal.from(this, mResourceConstructed));
1631d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            }
1641d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        } catch (OneCameraAccessException ex) {
1651d518e63212290741d66aaf34356bd3897bb609eSenpo Hu            return Optional.of((State) StateFatal.from(this, mResourceConstructed));
1661d518e63212290741d66aaf34356bd3897bb609eSenpo Hu        }
167de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu
168de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // Must do this before calling ResourceOpenedCamera.startPreview()
169de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // since SurfaceTexture.setDefaultBufferSize() needs to be called
170de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // before starting preview. Otherwise the size of preview video stream
171de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        // will be wrong.
172de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        mResourceSurfaceTexture.get().setPreviewSize(previewSize);
173de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu
174d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        OneCamera.CaptureReadyCallback captureReadyCallback =
175d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new OneCamera.CaptureReadyCallback() {
176d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
177d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public void onSetupFailed() {
178d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        getStateMachine().processEvent(new EventOnStartPreviewFailed());
179d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
180d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
181d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
182d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public void onReadyForCapture() {
183d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        getStateMachine().processEvent(new EventOnStartPreviewSucceeded());
184d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
185d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
186d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
1878b4309b20d64b15bc49d5cdc891d09208f009f06Senpo Hu        // Start preview right away. Don't dispatch it on other threads or it
1888b4309b20d64b15bc49d5cdc891d09208f009f06Senpo Hu        // will cause race condition. b/19522251.
1898b4309b20d64b15bc49d5cdc891d09208f009f06Senpo Hu        mResourceOpenedCamera.get().startPreview(
190d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                mResourceSurfaceTexture.get().createPreviewSurface(), captureReadyCallback);
19124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return Optional.absent();
19224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
19324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
19424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
19524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onLeave() {
19624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceConstructed.close();
19724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceSurfaceTexture.close();
19824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceOpenedCamera.close();
19924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
20024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu}
201