182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar/*
282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * Copyright (C) 2014 The Android Open Source Project
382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar *
482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * in compliance with the License. You may obtain a copy of the License at
682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar *
782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * http://www.apache.org/licenses/LICENSE-2.0
882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar *
982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * Unless required by applicable law or agreed to in writing, software distributed under the License
1082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
1182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * or implied. See the License for the specific language governing permissions and limitations under
1282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * the License.
1382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar */
1482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
1582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharpackage com.android.camera.burst;
1682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
1724069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberlingimport android.content.Context;
180f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberlingimport android.graphics.SurfaceTexture;
19b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekharimport android.view.Surface;
2082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
21a7216e47fcfae70fd65a25753a93ec246be3633fShashi Shekharimport com.android.camera.app.OrientationManager.DeviceOrientation;
22b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekharimport com.android.camera.async.MainThread;
23b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekharimport com.android.camera.burst.BurstController.ImageStreamProperties;
2482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharimport com.android.camera.debug.Log;
2582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharimport com.android.camera.debug.Log.Tag;
26a7216e47fcfae70fd65a25753a93ec246be3633fShashi Shekharimport com.android.camera.one.OneCamera.Facing;
2782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharimport com.android.camera.session.CaptureSession;
2824069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberlingimport com.android.camera.session.StackSaver;
2982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
3082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharimport java.util.Map;
3182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharimport java.util.concurrent.atomic.AtomicReference;
3282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
3382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar/**
3482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * Helper to manage burst, listen to burst results and saves media items.
3582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * <p/>
3624069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling * The UI feedback is rudimentary in form of a toast that is displayed on start
3724069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling * of the burst and when artifacts are saved. TODO: Move functionality of saving
3824069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling * burst items to a {@link com.android.camera.processing.ProcessingTask} and
3924069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling * change API to use {@link com.android.camera.processing.ProcessingService}.
4082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar * TODO: Hook UI to the listener.
4182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar */
4282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekharclass BurstFacadeImpl implements BurstFacade {
4382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    /**
4482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     * The state of the burst module.
4582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     */
4682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    private static enum BurstModuleState {
4782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar        IDLE,
4882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar        RUNNING,
4982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar        STOPPING
5082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    }
5182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
5282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    private static final Tag TAG = new Tag("BurstFacadeImpl");
5382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
54b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    private static final int DEFAULT_PREVIEW_WIDTH = 320;
55b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    private static final int DEFAULT_PREVIEW_HEIGHT = 240;
56f100ab2f2e0ea16c45658d7c227a3cdfbee71b13Shashi Shekhar
5782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    private final AtomicReference<BurstModuleState> mBurstModuleState =
5882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar            new AtomicReference<BurstModuleState>(BurstModuleState.IDLE);
59b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    private final AtomicReference<BurstTaker> mBurstTaker =
60b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            new AtomicReference<>(null);
6182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
6282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    private final BurstController mBurstController;
6324069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling
6424069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling    /** A stack saver for the outstanding burst request. */
6524069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling    private StackSaver mActiveStackSaver;
6624069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling
6782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    /**
6882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     * Listener for burst controller. Saves the results and interacts with the
6982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     * UI.
7082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     */
7182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    private final BurstResultsListener mBurstResultsListener =
7282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar            new BurstResultsListener() {
7382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                @Override
7482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                public void onBurstStarted() {
7582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                }
7682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
7782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                @Override
7882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                public void onBurstError(Exception error) {
7982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                    Log.e(TAG, "Exception while running the burst" + error);
8082d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                }
8182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
8282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                @Override
8382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                public void onBurstCompleted(BurstResult burstResult) {
84b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                    BurstResultsSaver.saveBurstResultsInBackground(burstResult, mActiveStackSaver,
85b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                            new Runnable() {
86b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                        @Override
87b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                        public void run() {
889f0a07d216d4eb6e2523d567f34580467d8ce83bShashi Shekhar                            mBurstModuleState.set(BurstModuleState.IDLE);
89b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                            }
90b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                        });
9182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                }
9282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
9382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                @Override
9482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                public void onArtifactCountAvailable(
9582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                        final Map<String, Integer> artifactTypeCount) {
96b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                    BurstResultsSaver.logArtifactCount(artifactTypeCount);
9782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                }
9882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar            };
9982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
100b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    private final OrientationLockController mOrientationLockController;
10124069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling    private final BurstReadyStateChangeListener mReadyStateListener;
10282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
103b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    private final AtomicReference<SurfaceTextureContainer> mSurfaceTextureContainer =
104b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            new AtomicReference<>();
1050f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling
10682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    /**
10782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     * Create a new BurstManagerImpl instance.
10882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     *
109b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar     * @param appContext the application context
110b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar     * @param orientationLockController for locking orientation when burst is
111b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar     *            running.
11224069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling     * @param readyStateListener gets called when the ready state of Burst
11324069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling     *            changes.
11482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar     */
115b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    public BurstFacadeImpl(Context appContext,
116b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            OrientationLockController orientationLockController,
117b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            BurstReadyStateChangeListener readyStateListener) {
118b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        mOrientationLockController = orientationLockController;
119b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        mBurstController = new BurstControllerImpl(appContext);
12024069e7a9cc9b4f908f18a71301285ccf5e164f6Sascha Haeberling        mReadyStateListener = readyStateListener;
12182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    }
12282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
12382d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    @Override
124e48cd5405840c530d4beefca84674c4919a77edbSascha Haeberling    public void startBurst(CaptureSession.CaptureSessionCreator captureSessionCreator,
125b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            DeviceOrientation deviceOrientation,
126b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            Facing cameraFacing,
127b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            int imageOrientationDegrees) {
128b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        MainThread.checkMainThread();
129b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        if (mBurstTaker.get() != null &&
130b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                mBurstModuleState.compareAndSet(BurstModuleState.IDLE,
131b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                        BurstModuleState.RUNNING)) {
132e48cd5405840c530d4beefca84674c4919a77edbSascha Haeberling            // Only create a session if we do start a burst.
133e48cd5405840c530d4beefca84674c4919a77edbSascha Haeberling            CaptureSession captureSession = captureSessionCreator.createAndStartEmpty();
134b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            mActiveStackSaver = captureSession.getStackSaver();
135b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar
136b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            mOrientationLockController.lockOrientation();
137b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            // Disable the shutter button.
138b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            mReadyStateListener.onBurstReadyStateChanged(false);
139b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar
140b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            Log.d(TAG, "Starting burst. Device orientation: " + deviceOrientation.getDegrees()
141b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                    + " image orientation: " + imageOrientationDegrees);
142b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            int width = DEFAULT_PREVIEW_WIDTH;
143b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            int height = DEFAULT_PREVIEW_HEIGHT;
144b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            if (imageOrientationDegrees % 180 == 90) {
145b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                int tmp = width;
146b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                width = height;
147b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                height = tmp;
14882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar            }
149b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar
150b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            ImageStreamProperties imageStreamProperties =
151b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                    new ImageStreamProperties(width, height,
152b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                            imageOrientationDegrees, cameraFacing == Facing.FRONT);
153b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            EvictionHandler evictionHandler =
154b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                    mBurstController.startBurst(
155b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                            mSurfaceTextureContainer.get().getSurfaceTexture(),
156b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                            imageStreamProperties,
1574361352633d1e106c1574c02ddd27c8891c5ee78Shashi Shekhar                            mBurstResultsListener,
1584361352633d1e106c1574c02ddd27c8891c5ee78Shashi Shekhar                            captureSession);
159b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar
160b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            // Start burst.
161b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            mBurstTaker.get().startBurst(evictionHandler, mBurstController);
162b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        } else {
163b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            Log.e(TAG, "Cannot start burst.");
16482d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar        }
16582d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    }
16682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
16782d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    @Override
168dd7c15c4b89a7410545f9efe62e2dea18cd1aaa8Sascha Haeberling    public boolean stopBurst() {
169b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        MainThread.checkMainThread();
170a7216e47fcfae70fd65a25753a93ec246be3633fShashi Shekhar            boolean wasStopped = false;
17182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar            if (mBurstModuleState.compareAndSet(BurstModuleState.RUNNING,
17282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar                    BurstModuleState.STOPPING)) {
173b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                mBurstTaker.get().stopBurst();
174b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar                wasStopped = true;
1759f0a07d216d4eb6e2523d567f34580467d8ce83bShashi Shekhar                reEnableUI();
17682d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar            }
177a7216e47fcfae70fd65a25753a93ec246be3633fShashi Shekhar            return wasStopped;
1780f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    }
1790f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling
1800f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    @Override
181b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    public Surface getInputSurface() {
182b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        return mSurfaceTextureContainer.get().getSurface();
1830f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    }
1840f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling
1850f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    @Override
186b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    public void initialize(SurfaceTexture surfaceTexture) {
187b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        MainThread.checkMainThread();
188b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        // TODO: Use preview sizes from Camera API here instead of using the
189b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        // default.
190b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        surfaceTexture.setDefaultBufferSize(DEFAULT_PREVIEW_WIDTH, DEFAULT_PREVIEW_HEIGHT);
1910f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling
192b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        // Detach from GL context, to allow frame distributor to attach to the
193b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        // GL context.
194b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        surfaceTexture.detachFromGLContext();
195b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        mSurfaceTextureContainer.set(new SurfaceTextureContainer(surfaceTexture));
1960f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    }
1970f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling
1980f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    @Override
199b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    public void release() {
200b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        MainThread.checkMainThread();
201b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        stopBurst();
202b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        if (mSurfaceTextureContainer.get() != null) {
203b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            mSurfaceTextureContainer.get().close();
204b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar            mSurfaceTextureContainer.set(null);
2050f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling        }
2060f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    }
2070f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling
2080f989bab3bda93546d3eafd0a065e1162f83d8f0Sascha Haeberling    @Override
209b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    public void setBurstTaker(BurstTaker burstTaker) {
210b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        mBurstTaker.set(burstTaker);
21182d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    }
21282d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar
213b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar    private void reEnableUI() {
214b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        MainThread.checkMainThread();
215b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        mOrientationLockController.unlockOrientation();
216b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        // Re-enable the shutter button.
217b4b27f2c7738cd5e3f31a281d66a33f4698810b3Shashi Shekhar        mReadyStateListener.onBurstReadyStateChanged(true);
21882d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar    }
21982d592f64966766ac4e4181e08b0d2989d4ed9c3Shashi Shekhar}
220