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
19d1f25e8507bc27a85853bb718c365d79a838dc33Paul Rohdeimport android.graphics.Bitmap;
20c7ef4da1e06ad9a4b88daed9ffc49bdb415fd011Senpo Huimport android.graphics.Matrix;
21d1f25e8507bc27a85853bb718c365d79a838dc33Paul Rohdeimport android.graphics.Point;
22c7ef4da1e06ad9a4b88daed9ffc49bdb415fd011Senpo Huimport android.graphics.PointF;
23c7ef4da1e06ad9a4b88daed9ffc49bdb415fd011Senpo Huimport android.graphics.RectF;
24d1f25e8507bc27a85853bb718c365d79a838dc33Paul Rohdeimport android.media.MediaActionSound;
25d1f25e8507bc27a85853bb718c365d79a838dc33Paul Rohdeimport android.net.Uri;
2624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
2724be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.async.RefCountBase;
2824be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.captureintent.CaptureIntentConfig;
298aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Huimport com.android.camera.captureintent.CaptureIntentModuleUI;
3024be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.captureintent.PictureDecoder;
31d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventCameraBusy;
32d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventCameraQuickExpose;
33d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventCameraReady;
34edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Huimport com.android.camera.captureintent.event.EventClickOnCameraKey;
35d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventFastPictureBitmapAvailable;
36d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventOnSurfaceTextureUpdated;
37d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventOnTextureViewLayoutChanged;
38d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventPause;
39d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventPictureCompressed;
40d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventPictureDecoded;
41d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventTapOnCancelShutterButton;
42d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventTapOnPreview;
43d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventTapOnShutterButton;
44d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventTapOnSwitchCameraButton;
45d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventTimerCountDownToZero;
46d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.event.EventZoomRatioChanged;
471d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.resource.ResourceCaptureTools;
481d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.resource.ResourceCaptureToolsImpl;
491d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.resource.ResourceConstructed;
501d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.resource.ResourceOpenedCamera;
511d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.resource.ResourceSurfaceTexture;
521d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.stateful.EventHandler;
53d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.State;
54d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.StateImpl;
5583d86d3aad276b0c15bfc2767d27c9f0354a104dSenpo Huimport com.android.camera.debug.Log;
561d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.device.CameraId;
5724be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.one.OneCamera;
58b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohdeimport com.android.camera.one.OneCamera.Facing;
59cc6139467c1c9545de1f098d938409e182c9b7adSenpo Huimport com.android.camera.one.OneCameraAccessException;
60cc6139467c1c9545de1f098d938409e182c9b7adSenpo Huimport com.android.camera.one.OneCameraCharacteristics;
611b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Huimport com.android.camera.session.CaptureSession;
6224be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.session.CaptureSessionManager;
6324be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.settings.Keys;
6424be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.settings.SettingsManager;
651b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Huimport com.android.camera.ui.CountDownView;
668aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Huimport com.android.camera.ui.TouchCoordinate;
6724be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.ui.focus.FocusController;
68a6572422e8940e176e3630c23a331927b5b08853Senpo Huimport com.android.camera.util.Size;
69a6572422e8940e176e3630c23a331927b5b08853Senpo Hu
70d1f25e8507bc27a85853bb718c365d79a838dc33Paul Rohdeimport com.google.common.base.Optional;
7124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
72edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Huimport javax.annotation.Nullable;
73edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
7424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu/**
7524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * Represents a state that allows users to take a picture. The capture UI
7624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * should be presented in this state so users can perform actions:
7724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * 1. tap on shutter button to take a picture.
7824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * 2. tap on viewfinder to focus.
7924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * 3. switch between front and back camera.
8024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu */
81d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hupublic final class StateReadyForCapture extends StateImpl {
8283d86d3aad276b0c15bfc2767d27c9f0354a104dSenpo Hu    private static final Log.Tag TAG = new Log.Tag("StateReadyCap");
8383d86d3aad276b0c15bfc2767d27c9f0354a104dSenpo Hu
8424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final RefCountBase<ResourceCaptureTools> mResourceCaptureTools;
8524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
86de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu    private boolean mShouldUpdateTransformOnNextSurfaceTextureUpdate;
8724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private boolean mIsCountingDown;
8824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private boolean mIsTakingPicture;
8924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private boolean mIsDecodingPicture;
9024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
9124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public static StateReadyForCapture from(
9224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            StateStartingPreview startingPreview,
9324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceConstructed> resourceConstructed,
9424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture,
951b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            RefCountBase<ResourceOpenedCamera> resourceOpenedCamera) {
9680aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        return new StateReadyForCapture(
971b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                startingPreview, resourceConstructed, resourceSurfaceTexture, resourceOpenedCamera);
9824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
9924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
10024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public static StateReadyForCapture from(
10124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            StateReviewingPicture reviewingPicture,
10224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceCaptureTools> resourceCaptureTools) {
10324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return new StateReadyForCapture(reviewingPicture, resourceCaptureTools);
10424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
10524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
10624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private StateReadyForCapture(
107d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            State previousState,
10880aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            RefCountBase<ResourceConstructed> resourceConstructed,
10980aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu            RefCountBase<ResourceSurfaceTexture> resourceSurfaceTexture,
1101b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            RefCountBase<ResourceOpenedCamera> resourceOpenedCamera) {
111d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        super(previousState);
112d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        mResourceCaptureTools = ResourceCaptureToolsImpl.create(
1131b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                resourceConstructed, resourceSurfaceTexture, resourceOpenedCamera);
11480aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mIsCountingDown = false;
11580aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mIsTakingPicture = false;
11680aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mIsDecodingPicture = false;
117de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        mShouldUpdateTransformOnNextSurfaceTextureUpdate = true;
118d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        registerEventHandlers();
11980aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu    }
12080aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu
12180aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu    private StateReadyForCapture(
122d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            State previousState,
12324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            RefCountBase<ResourceCaptureTools> resourceCaptureTools) {
124d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        super(previousState);
12524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceCaptureTools = resourceCaptureTools;
12680aed3c513dc6a6670e25ef6e11bc71ab6a2d9fdSenpo Hu        mResourceCaptureTools.addRef();  // Will be balanced in onLeave().
12724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mIsCountingDown = false;
12824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mIsTakingPicture = false;
12924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mIsDecodingPicture = false;
130de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu        mShouldUpdateTransformOnNextSurfaceTextureUpdate = true;
131d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        registerEventHandlers();
132d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    }
133d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
134edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu    private void takePicture(@Nullable final TouchCoordinate touchPointInsideShutterButton) {
135edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        final int countDownDuration =
136edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                mResourceCaptureTools.get().getResourceConstructed().get()
137edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        .getSettingsManager().getInteger(
138edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        SettingsManager.SCOPE_GLOBAL, Keys.KEY_COUNTDOWN_DURATION);
139edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
140edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        /** Prepare a CaptureLoggingInfo object. */
141edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        final ResourceCaptureTools.CaptureLoggingInfo captureLoggingInfo
142edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                = new ResourceCaptureTools.CaptureLoggingInfo() {
143edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            @Override
144edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            public TouchCoordinate getTouchPointInsideShutterButton() {
145edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                return touchPointInsideShutterButton;
146edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            }
147edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
148edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            @Override
149edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            public int getCountDownDuration() {
150edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                return countDownDuration;
151edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            }
152edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        };
153edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
154edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        /** Start counting down if the duration is not zero. */
155edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        if (countDownDuration > 0) {
156edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            startCountDown(countDownDuration, captureLoggingInfo);
157edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        } else {
158edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            /** Otherwise, just take a picture immediately. */
159edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            takePictureNow(captureLoggingInfo);
160edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        }
161edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu    }
162edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
163edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu    private void startCountDown(
164edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            final int countDownDuration,
165edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            final ResourceCaptureTools.CaptureLoggingInfo captureLoggingInfo) {
166edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        mIsCountingDown = true;
167edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
168edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            @Override
169edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            public void run() {
170edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                CaptureIntentModuleUI moduleUI = mResourceCaptureTools.get().getModuleUI();
171edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                moduleUI.setCountdownFinishedListener(
172edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        new CountDownView.OnCountDownStatusListener() {
173edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            @Override
174edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            public void onRemainingSecondsChanged(
175edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                                    int remainingSeconds) {
176edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                                mResourceCaptureTools.get()
177edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                                        .playCountDownSound(remainingSeconds);
178edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            }
179edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
180edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            @Override
181edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            public void onCountDownFinished() {
182edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                                getStateMachine().processEvent(
183edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                                        new EventTimerCountDownToZero(
184edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                                                captureLoggingInfo));
185edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            }
186edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        });
187edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                moduleUI.startCountdown(countDownDuration);
188edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            }
189edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        });
190edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu    }
191edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
192edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu    private void cancelCountDown() {
193edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        // Cancel in this state means that the countdown was cancelled.
194edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        mIsCountingDown = false;
195edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
196edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            @Override
197edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            public void run() {
198edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                mResourceCaptureTools.get().getModuleUI().cancelCountDown();
199edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                mResourceCaptureTools.get().getModuleUI().showPictureCaptureUI();
200edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            }
201edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        });
202edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu    }
203edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu
204e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu    private void takePictureNow(ResourceCaptureTools.CaptureLoggingInfo captureLoggingInfo) {
205e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu        mIsTakingPicture = true;
206e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu        mResourceCaptureTools.get().takePictureNow(mPictureCallback, captureLoggingInfo);
207e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu    }
208e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu
209d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    private void registerEventHandlers() {
210d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventPause. */
211d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventPause> pauseHandler = new EventHandler<EventPause>() {
212d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            @Override
213d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            public Optional<State> processEvent(EventPause event) {
214d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                return Optional.of((State) StateBackgroundWithSurfaceTexture.from(
215d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        StateReadyForCapture.this,
216d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceCaptureTools.get().getResourceConstructed(),
217d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceCaptureTools.get().getResourceSurfaceTexture()));
218d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            }
219d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        };
220d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventPause.class, pauseHandler);
221d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
222d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnSurfaceTextureUpdated. */
223d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnSurfaceTextureUpdated> onSurfaceTextureUpdatedHandler =
224d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnSurfaceTextureUpdated>() {
225d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
226d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnSurfaceTextureUpdated event) {
227d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        if (mShouldUpdateTransformOnNextSurfaceTextureUpdate) {
228d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mShouldUpdateTransformOnNextSurfaceTextureUpdate = false;
229a6572422e8940e176e3630c23a331927b5b08853Senpo Hu
230a6572422e8940e176e3630c23a331927b5b08853Senpo Hu                            // We have to provide a preview layout size to
231a6572422e8940e176e3630c23a331927b5b08853Senpo Hu                            // ResourceSurfaceTexture. Otherwise, it will
232a6572422e8940e176e3630c23a331927b5b08853Senpo Hu                            // not be able to calculate transform matrix.
233a6572422e8940e176e3630c23a331927b5b08853Senpo Hu                            Size previewSurfaceSize = mResourceCaptureTools.get().getModuleUI()
234a6572422e8940e176e3630c23a331927b5b08853Senpo Hu                                    .getPreviewSurfaceSize();
235d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mResourceCaptureTools.get().getResourceSurfaceTexture().get()
236a6572422e8940e176e3630c23a331927b5b08853Senpo Hu                                    .setPreviewLayoutSize(previewSurfaceSize);
237a6572422e8940e176e3630c23a331927b5b08853Senpo Hu
2388950eeb4deed45538d5e5143cd6d0282ed325746Senpo Hu                            removeEventHandler(EventOnSurfaceTextureUpdated.class);
239d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
240d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
241d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
242d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
243d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventOnSurfaceTextureUpdated.class, onSurfaceTextureUpdatedHandler);
244d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
245d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventOnTextureViewLayoutChanged. */
246d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventOnTextureViewLayoutChanged> onTextureViewLayoutChangedHandler =
247d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventOnTextureViewLayoutChanged>() {
248d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
249d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventOnTextureViewLayoutChanged event) {
250d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceCaptureTools.get().getResourceSurfaceTexture().get()
251d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                .setPreviewLayoutSize(event.getLayoutSize());
252d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
253d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
254d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
255d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(
256d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                EventOnTextureViewLayoutChanged.class, onTextureViewLayoutChangedHandler);
257d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
258d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventCameraBusy. */
259d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(
260d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                EventCameraBusy.class, mEventCameraBusyHandler);
261d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
262d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventCameraReady. */
263d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(
264d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                EventCameraReady.class, mEventCameraReadyHandler);
265d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
266d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventTapOnShutterButton. */
267d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventTapOnShutterButton> tapOnShutterButtonHandler =
268d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventTapOnShutterButton>() {
269d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
2708aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu                    public Optional<State> processEvent(final EventTapOnShutterButton event) {
271edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        takePicture(event.getTouchCoordinate());
272edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        return NO_CHANGE;
273edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                    }
274edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                };
275edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        setEventHandler(EventTapOnShutterButton.class, tapOnShutterButtonHandler);
2768aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu
277edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        /** Handles EventClickOnCameraKey */
278edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        EventHandler<EventClickOnCameraKey> clickOnVolumeKeyHandler =
279edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                new EventHandler<EventClickOnCameraKey>() {
280edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                    @Override
281edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                    public Optional<State> processEvent(EventClickOnCameraKey event) {
282edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        if (mIsCountingDown) {
283edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                            cancelCountDown();
284d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            return NO_CHANGE;
285d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
286edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        takePicture(null);
287d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
288d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
289d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
290edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        setEventHandler(EventClickOnCameraKey.class, clickOnVolumeKeyHandler);
291d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
292d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventTimerCountDownToZero. */
293d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventTimerCountDownToZero> timerCountDownToZeroHandler =
294d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventTimerCountDownToZero>() {
295d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
296d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventTimerCountDownToZero event) {
297d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        if (mIsCountingDown) {
298d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mIsCountingDown = false;
299e5c19b4acc3be9b70e665627f76d082c6fc3289dSenpo Hu                            takePictureNow(event.getCaptureLoggingInfo());
300d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
301d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
302d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
303d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
304d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventTimerCountDownToZero.class, timerCountDownToZeroHandler);
305d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
306d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventTapOnSwitchCameraButton. */
307d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventTapOnSwitchCameraButton> tapOnSwitchCameraButtonHandler =
308d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventTapOnSwitchCameraButton>() {
309d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
310d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventTapOnSwitchCameraButton event) {
311cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        final ResourceConstructed resourceConstructed =
312cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                mResourceCaptureTools.get().getResourceConstructed().get();
313cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu
314d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        // Freeze the screen.
315d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
316d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            @Override
317d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            public void run() {
318cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                resourceConstructed.getModuleUI().freezeScreenUntilPreviewReady();
319d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            }
320d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        });
321d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
322cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        OneCamera.Facing cameraFacing =
323cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                resourceConstructed.getCameraFacingSetting().getCameraFacing();
3241d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                        CameraId cameraId =  resourceConstructed.getOneCameraManager()
3251d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                              .findFirstCameraFacing(cameraFacing);
326cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        OneCameraCharacteristics characteristics;
327cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        try {
3281d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                            characteristics = resourceConstructed.getOneCameraManager()
3291d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                                    .getOneCameraCharacteristics(cameraId);
330cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        } catch (OneCameraAccessException ex) {
331cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                            return Optional.of((State) StateFatal.from(
332cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                    StateReadyForCapture.this,
333cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                    mResourceCaptureTools.get().getResourceConstructed()));
334cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        }
335cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu
336d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return Optional.of((State) StateOpeningCamera.from(
337d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                StateReadyForCapture.this,
338d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                mResourceCaptureTools.get().getResourceConstructed(),
339cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                mResourceCaptureTools.get().getResourceSurfaceTexture(),
340cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                cameraFacing,
3411d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                                cameraId,
342cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                                characteristics));
343d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
344d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
345d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventTapOnSwitchCameraButton.class, tapOnSwitchCameraButtonHandler);
346d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
347d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventTapOnPreview. */
348d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventTapOnPreview> tapOnPreviewHandler = new EventHandler<EventTapOnPreview>() {
349d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            @Override
350d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            public Optional<State> processEvent(EventTapOnPreview event) {
351b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                OneCameraCharacteristics cameraCharacteristics = mResourceCaptureTools.get()
352b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                      .getResourceOpenedCamera().get().getCameraCharacteristics();
353b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                if (cameraCharacteristics.isAutoExposureSupported() ||
354b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                      cameraCharacteristics.isAutoFocusSupported()) {
355b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    final Point tapPoint = event.getTapPoint();
356b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    mResourceCaptureTools.get().getFocusController().showActiveFocusAt(
357b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                          tapPoint.x, tapPoint.y);
358b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde
359b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    RectF previewRect = mResourceCaptureTools.get().getModuleUI().getPreviewRect();
360b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    int rotationDegree = mResourceCaptureTools.get().getResourceConstructed().get()
361b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                          .getOrientationManager().getDisplayRotation().getDegrees();
362b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde
363b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    // Normalize coordinates to [0,1] per CameraOne API.
364b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    float points[] = new float[2];
365b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    points[0] = (tapPoint.x - previewRect.left) / previewRect.width();
366b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    points[1] = (tapPoint.y - previewRect.top) / previewRect.height();
367b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde
368b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    // Rotate coordinates to portrait orientation per CameraOne API.
369b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    Matrix rotationMatrix = new Matrix();
370b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    rotationMatrix.setRotate(rotationDegree, 0.5f, 0.5f);
371b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    rotationMatrix.mapPoints(points);
372b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde
373b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    // Invert X coordinate on front camera since the display is mirrored.
374b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    if (cameraCharacteristics.getCameraDirection() == Facing.FRONT) {
375b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                        points[0] = 1 - points[0];
376b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    }
377b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde
378b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                    mResourceCaptureTools.get().getResourceOpenedCamera().get()
379b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                          .triggerFocusAndMeterAtPoint(
380b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                                new PointF(points[0], points[1]));
381b55bc734e5d9284cd739bc384a190dbe155d540dPaul Rohde                }
382d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
383d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                return NO_CHANGE;
384d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            }
385d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        };
386d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventTapOnPreview.class, tapOnPreviewHandler);
387d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
388d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventZoomRatioChanged. */
389d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventZoomRatioChanged> zoomRatioChangedHandler =
390d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventZoomRatioChanged>() {
391d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
392d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventZoomRatioChanged event) {
393d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        mResourceCaptureTools.get().getResourceOpenedCamera().get().setZoomRatio(
394d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                event.getZoomRatio());
395d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
396d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
397d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
398d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventZoomRatioChanged.class, zoomRatioChangedHandler);
399d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
400d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventPictureCompressed. */
401d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventPictureCompressed> pictureCompressedHandler =
402d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventPictureCompressed>() {
403d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
404d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventPictureCompressed event) {
405d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        if (mIsTakingPicture) {
406d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mIsTakingPicture = false;
407d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mIsDecodingPicture = true;
408d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
409d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            final byte[] pictureData = event.getPictureData();
410d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            final int pictureOrientation = event.getOrientation();
411d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mResourceCaptureTools.get().getResourceConstructed().get().getCameraHandler().post(
412d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    new Runnable() {
413d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                        @Override
414d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                        public void run() {
415d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                            final Bitmap pictureBitmap = PictureDecoder.decode(
416d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                                    pictureData,
417d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                                    CaptureIntentConfig.DOWN_SAMPLE_FACTOR,
418d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                                    pictureOrientation,
419d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                                    false);
420d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                            getStateMachine().processEvent(
421d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                                    new EventPictureDecoded(pictureBitmap, pictureData));
422d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                        }
423d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    });
424d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
425d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
426d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
427d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
428d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventPictureCompressed.class, pictureCompressedHandler);
429d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
430d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventPictureDecoded. */
431d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventPictureDecoded> pictureDecodedHandler =
432d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventPictureDecoded>() {
433d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
434d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventPictureDecoded event) {
435bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        // Do nothing if we are not in the decoding image sub-state. There is a
436bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        // chance that EventPictureDecoded for an old image might come after people
437bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        // hitting retake button. We have to ignore it or it will take us to
438bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        // StateReviewingPicture.
439bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        if (!mIsDecodingPicture) {
440bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                            return NO_CHANGE;
441bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        }
442bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu
443bc75813126be7e9518e821fae31471db5ec3fe1aSenpo Hu                        mIsDecodingPicture = false;
444d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return Optional.of((State) StateReviewingPicture.from(
445d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                StateReadyForCapture.this, mResourceCaptureTools,
446d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                event.getPictureBitmap(), Optional.of(event.getPictureData())));
447d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
448d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
449d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventPictureDecoded.class, pictureDecodedHandler);
450d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
451d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventFastPictureBitmapAvailable. */
452d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventFastPictureBitmapAvailable> fastPictureBitmapAvailableHandler =
453d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventFastPictureBitmapAvailable>() {
454d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
455d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventFastPictureBitmapAvailable event) {
456d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        if (mIsTakingPicture && !mIsDecodingPicture) {
457d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            return Optional.of((State) StateReviewingPicture.from(
458d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    StateReadyForCapture.this, mResourceCaptureTools,
459d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    event.getThumbnailBitmap(), Optional.<byte[]>absent()));
460d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
461d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
462d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
463d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
464d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventFastPictureBitmapAvailable.class, fastPictureBitmapAvailableHandler);
465d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
466d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventCameraQuickExpose. */
467d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventCameraQuickExpose> cameraQuickExposeHandler =
468d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventCameraQuickExpose>() {
469d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
470d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventCameraQuickExpose event) {
471d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        if (mIsTakingPicture) {
472d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
473d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                @Override
474d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                public void run() {
475ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava
476ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                    ResourceConstructed resourceConstructed =
477ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                            mResourceCaptureTools.get().getResourceConstructed()
478ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                                    .get();
479ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                    // Freeze the screen.
480ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                    resourceConstructed.getModuleUI()
481ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                            .freezeScreenUntilPreviewReady();
482d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    // Disable shutter button.
483ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                    mResourceCaptureTools.get().getModuleUI()
484ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                            .setShutterButtonEnabled(false);
485d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    // Starts the short version of the capture animation UI.
486ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                    mResourceCaptureTools.get().getModuleUI()
487ea48e2e02549198b7c3fca075328ee35845d693eGabriel Nava                                            .startFlashAnimation(true);
488d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    mResourceCaptureTools.get().getMediaActionSound().play(
489d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                            MediaActionSound.SHUTTER_CLICK);
490d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                }
491d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            });
492d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
493d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
494d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
495d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
496d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventCameraQuickExpose.class, cameraQuickExposeHandler);
497d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
498d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        /** Handles EventTapOnCancelShutterButton. */
499d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        EventHandler<EventTapOnCancelShutterButton> tapOnCancelShutterButtonHandler =
500d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                new EventHandler<EventTapOnCancelShutterButton>() {
501d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    @Override
502d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    public Optional<State> processEvent(EventTapOnCancelShutterButton event) {
503edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                        cancelCountDown();
504d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        return NO_CHANGE;
505d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
506d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                };
507d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        setEventHandler(EventTapOnCancelShutterButton.class, tapOnCancelShutterButtonHandler);
50824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
50924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
51024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
51124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public Optional<State> onEnter() {
5121b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        // Register various listeners. These will be unregistered in onLeave().
5131b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        final OneCamera camera =
5141b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                mResourceCaptureTools.get().getResourceOpenedCamera().get().getCamera();
5151b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        camera.setFocusDistanceListener(mResourceCaptureTools.get().getFocusController());
5161b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        camera.setFocusStateListener(mFocusStateListener);
5171b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        camera.setReadyStateChangedListener(mReadyStateChangedListener);
5181b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        mResourceCaptureTools.get().getCaptureSessionManager()
5191b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                .addSessionListener(mCaptureSessionListener);
5201b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
5211b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        // Display capture UI.
52224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
52324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            @Override
52424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            public void run() {
525924c693b2c70d5332ad86d39550c99cb8ff696edSascha Haeberling                mResourceCaptureTools.get().getModuleUI().cancelCountDown();
52624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                mResourceCaptureTools.get().getModuleUI().showPictureCaptureUI();
5271b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                mResourceCaptureTools.get().getModuleUI().initializeZoom(
5281b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                        mResourceCaptureTools.get().getResourceOpenedCamera().get().getZoomRatio());
52924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            }
53024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        });
53124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return NO_CHANGE;
53224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
53324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
53424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
53524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onLeave() {
5361b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        final OneCamera camera =
5371b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                mResourceCaptureTools.get().getResourceOpenedCamera().get().getCamera();
5381b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        camera.setFocusDistanceListener(null);
5391b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        camera.setFocusStateListener(null);
5401b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        camera.setReadyStateChangedListener(null);
5411b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
5421b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        mResourceCaptureTools.get().getCaptureSessionManager()
5431b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                .removeSessionListener(mCaptureSessionListener);
54424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mResourceCaptureTools.close();
54524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
54624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
547a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu    private void onFocusStateUpdated(OneCamera.AutoFocusState focusState) {
548a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu        final FocusController focusController = mResourceCaptureTools.get().getFocusController();
549a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu        switch (focusState) {
550a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu            case PASSIVE_SCAN:
551a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                focusController.showPassiveFocusAtCenter();
552a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                break;
553a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu            case ACTIVE_SCAN:
554a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                break;
555a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu            case PASSIVE_FOCUSED:
556a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu            case PASSIVE_UNFOCUSED:
557a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                focusController.clearFocusIndicator();
558a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                break;
559a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu            case ACTIVE_FOCUSED:
560a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu            case ACTIVE_UNFOCUSED:
561a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                focusController.clearFocusIndicator();
562a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                break;
563a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu        }
564a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu    }
565a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu
5661b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu    private final OneCamera.FocusStateListener mFocusStateListener =
5671b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            new OneCamera.FocusStateListener() {
5681b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
5691b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onFocusStatusUpdate(final OneCamera.AutoFocusState focusState,
5701b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                        final long frameNumber) {
571a27011ccd08c97465a1329b30e6b856f9c2d258fSenpo Hu                    onFocusStateUpdated(focusState);
5721b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
5731b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            };
5741b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
575d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    private final EventHandler<EventCameraBusy> mEventCameraBusyHandler =
576d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            new EventHandler<EventCameraBusy>() {
577d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                @Override
578d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                public Optional<State> processEvent(EventCameraBusy event) {
579d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
580d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        @Override
581d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        public void run() {
582d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mResourceCaptureTools.get().getModuleUI().setShutterButtonEnabled(
583d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                                    false);
584d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
585d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    });
586d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    return NO_CHANGE;
587d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                }
588d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            };
589d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
590d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu    private final EventHandler<EventCameraReady> mEventCameraReadyHandler =
591d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            new EventHandler<EventCameraReady>() {
592d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                @Override
593d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                public Optional<State> processEvent(EventCameraReady event) {
594d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    mResourceCaptureTools.get().getMainThread().execute(new Runnable() {
595d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        @Override
596d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        public void run() {
597d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            mResourceCaptureTools.get().getModuleUI().setShutterButtonEnabled(true);
598d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        }
599d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    });
600d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    return NO_CHANGE;
601d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                }
602d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            };
603d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu
6041b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu    private final OneCamera.ReadyStateChangedListener mReadyStateChangedListener =
6051b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            new OneCamera.ReadyStateChangedListener() {
6061b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                /**
6071b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                 * Called when the camera is either ready or not ready to take a picture
6081b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                 * right now.
6091b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                 */
6101b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6111b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onReadyStateChanged(final boolean readyForCapture) {
612d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    if (readyForCapture) {
613d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        getStateMachine().processEvent(new EventCameraReady());
614d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    } else {
615d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                        getStateMachine().processEvent(new EventCameraBusy());
616d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    }
6171b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6181b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            };
6191b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6201b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu    private final OneCamera.PictureCallback mPictureCallback = new OneCamera.PictureCallback() {
6211b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        @Override
6221b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        public void onQuickExpose() {
623d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu            getStateMachine().processEvent(new EventCameraQuickExpose());
6241b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        }
6251b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6261b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        @Override
6271b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        public void onThumbnailResult(byte[] jpegData) {
6281b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        }
6291b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6301b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        @Override
6311b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        public void onPictureTaken(CaptureSession session) {
6321b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        }
6331b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6341b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        @Override
6351b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        public void onPictureSaved(Uri uri) {
6361b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        }
6371b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6381b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        @Override
6391b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        public void onPictureTakingFailed() {
6401b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        }
6411b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6421b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        @Override
6431b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        public void onTakePictureProgress(float progress) {
6441b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        }
6451b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu    };
6461b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6471b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu    private final CaptureSessionManager.SessionListener mCaptureSessionListener =
6481b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            new CaptureSessionManager.SessionListener() {
6491b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
650d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                public void onSessionThumbnailUpdate(Bitmap thumbnailBitmap) {
651d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    getStateMachine().processEvent(
652d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            new EventFastPictureBitmapAvailable(thumbnailBitmap));
6531b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6541b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6551b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
656d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                public void onSessionPictureDataUpdate(byte[] pictureData, int orientation) {
657d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                    getStateMachine().processEvent(
658d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu                            new EventPictureCompressed(pictureData, orientation));
6591b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6601b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6611b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6621b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onSessionQueued(Uri sessionUri) {
6631b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6641b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6651b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6661b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onSessionUpdated(Uri sessionUri) {
6671b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6681b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6691b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6701b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onSessionCaptureIndicatorUpdate(Bitmap bitmap, int rotationDegrees) {
6711b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6721b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6731b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6741b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onSessionDone(Uri sessionUri) {
6751b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6761b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6771b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6780460ef28c6970d646260584b7df0b2b3157a67eeSascha Haeberling                public void onSessionFailed(Uri sessionUri, int failureMessageId,
679698e271d2b263778bfa73d1e67d6e2cd2783c89ezafir                        boolean removeFromFilmstrip) {
6801b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6811b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6821b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6839c6f9b8085c2752758e0f5633958fd17cfc9307eSascha Haeberling                public void onSessionCanceled(Uri mediaUri) {
6849c6f9b8085c2752758e0f5633958fd17cfc9307eSascha Haeberling                }
6859c6f9b8085c2752758e0f5633958fd17cfc9307eSascha Haeberling
6869c6f9b8085c2752758e0f5633958fd17cfc9307eSascha Haeberling                @Override
6871b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                public void onSessionProgress(Uri sessionUri, int progress) {
6881b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6891b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu
6901b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                @Override
6910460ef28c6970d646260584b7df0b2b3157a67eeSascha Haeberling                public void onSessionProgressText(Uri sessionUri, int messageId) {
6921b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                }
6931b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            };
69424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu}