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;
1824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
1964d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.content.Intent;
2064d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.graphics.Point;
2164d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.graphics.SurfaceTexture;
2264d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.view.GestureDetector;
2364d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.view.KeyEvent;
2464d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.view.MotionEvent;
2564d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberlingimport android.view.View;
2664d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling
2724be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.CameraActivity;
2824be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.CameraModule;
2924be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.app.AppController;
3024be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.app.CameraAppUI;
3124be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.async.MainThread;
32cc6139467c1c9545de1f098d938409e182c9b7adSenpo Huimport com.android.camera.async.RefCountBase;
33cc6139467c1c9545de1f098d938409e182c9b7adSenpo Huimport com.android.camera.burst.BurstFacadeFactory;
34edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Huimport com.android.camera.captureintent.event.EventClickOnCameraKey;
351d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnSurfaceTextureAvailable;
361d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnSurfaceTextureDestroyed;
371d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnSurfaceTextureUpdated;
381d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventOnTextureViewLayoutChanged;
391d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventPause;
401d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventResume;
411d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventTapOnCancelShutterButton;
421d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventTapOnPreview;
431d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventTapOnShutterButton;
441d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.event.EventZoomRatioChanged;
45cc6139467c1c9545de1f098d938409e182c9b7adSenpo Huimport com.android.camera.captureintent.resource.ResourceConstructed;
46cc6139467c1c9545de1f098d938409e182c9b7adSenpo Huimport com.android.camera.captureintent.resource.ResourceConstructedImpl;
4724be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.captureintent.state.StateBackground;
481d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.captureintent.stateful.State;
49d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.StateMachine;
50d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Huimport com.android.camera.captureintent.stateful.StateMachineImpl;
5124be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.debug.Log;
5224be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.hardware.HardwareSpec;
531d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.one.OneCameraException;
541d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohdeimport com.android.camera.one.OneCameraModule;
5524be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.settings.SettingsManager;
5624be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.ui.PreviewStatusListener;
5724be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.ui.TouchCoordinate;
5824be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera.util.Size;
5924be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.camera2.R;
6024be7cc6d138129b4087ef28f114701de54aba3cSenpo Huimport com.android.ex.camera2.portability.CameraAgent;
6124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
6224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu/**
6324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu * The camera module that handles image capture intent.
6424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu */
6524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hupublic class CaptureIntentModule extends CameraModule {
66f8d390731abd88cc86354b377e1cb8beab0561afSenpo Hu    private static final Log.Tag TAG = new Log.Tag("CapIntModule");
6724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
6824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    /** The module UI. */
6924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final CaptureIntentModuleUI mModuleUI;
7024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
71cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu    /** The available resources after construction. */
72cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu    private final RefCountBase<ResourceConstructed> mResourceConstructed;
7324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
7424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    /** The module state machine. */
7524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final StateMachine mStateMachine;
7624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
778aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu    private TouchCoordinate mTouchPointInsideShutterButton;
788aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu
79f2399a5148ec6f101e9e0b3f137d33b443b79b8cAlan Newberger    public CaptureIntentModule(AppController appController, Intent intent,
801d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde            String settingScopeNamespace) throws OneCameraException {
8124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        super(appController);
8224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mModuleUI = new CaptureIntentModuleUI(
8324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                appController.getCameraAppUI(),
8424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                appController.getModuleLayoutRoot(),
8524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                mUIListener);
86d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        mStateMachine = new StateMachineImpl();
87cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu        mResourceConstructed = ResourceConstructedImpl.create(
88cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                intent,
89cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                mModuleUI,
90cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                settingScopeNamespace,
91cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                MainThread.create(),
92cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                appController.getAndroidContext(),
931d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                appController.getCameraOpener(),
941d84d7107686aa428ee2eeb1a8caf0ea3e43b1dfPaul Rohde                OneCameraModule.provideOneCameraManager(),
95cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                appController.getLocationManager(),
96cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                appController.getOrientationManager(),
97cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                appController.getSettingsManager(),
98cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                new BurstFacadeFactory.BurstFacadeStub(),
99cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                appController,
100cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                appController.getFatalErrorHandler());
101cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu        final State initialState = StateBackground.create(mStateMachine, mResourceConstructed);
10224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Set the initial state.
103d2d86155337a7dd9fd285a25c93e27dc05200ed1Senpo Hu        mStateMachine.setInitialState(initialState);
10424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
10524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
10624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
10724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onCameraAvailable(CameraAgent.CameraProxy cameraProxy) {
10824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Do nothing for capture intent.
10924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
11024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
11124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
11224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onShutterButtonFocus(boolean pressed) {
11324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Do nothing for capture intent.
11424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
11524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
11624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
1178aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu    public void onShutterCoordinate(TouchCoordinate touchCoordinate) {
1188aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu        mTouchPointInsideShutterButton = touchCoordinate;
11924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
12024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
12124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
12224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onShutterButtonClick() {
1238aefbc59ce6176f27efd47f4a568117bd4d9ea77Senpo Hu        mStateMachine.processEvent(new EventTapOnShutterButton(mTouchPointInsideShutterButton));
12424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
12524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
12624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
12724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onShutterButtonLongPressed() {
12824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Do nothing for capture intent.
12924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
13024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
13124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
13224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void init(
13324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            final CameraActivity activity, boolean isSecureCamera, boolean isCaptureIntent) {
134cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu        mResourceConstructed.get().getAppController()
135cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                .setPreviewStatusListener(mPreviewStatusListener);
13664d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling
13764d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling        // Issue cancel countdown event when the button is pressed.
13864d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling        // TODO: Make this part of the official API the way shutter button events are.
139cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu        mResourceConstructed.get().getAppController().getCameraAppUI()
140cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                .setCancelShutterButtonListener(new View.OnClickListener() {
141cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                    @Override
142cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                    public void onClick(View v) {
143cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                        mStateMachine.processEvent(new EventTapOnCancelShutterButton());
144cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                    }
145cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                });
14664d22d9caf0824739cb250575d69a56fe7f3fa3cSascha Haeberling
14724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
14824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
14924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
15024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void resume() {
15183d86d3aad276b0c15bfc2767d27c9f0354a104dSenpo Hu        mModuleUI.onModuleResumed();
1521b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        mStateMachine.processEvent(new EventResume());
15324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
15424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
15524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
15624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void pause() {
15724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        mModuleUI.setCountdownFinishedListener(null);
15883d86d3aad276b0c15bfc2767d27c9f0354a104dSenpo Hu        mModuleUI.onModulePaused();
1591b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu        mStateMachine.processEvent(new EventPause());
16024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
16124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
16224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
16324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void destroy() {
16424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Never called. Do nothing here.
16524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
16624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
16724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
16824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onPreviewVisibilityChanged(int visibility) {
16924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Do nothing.
17024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
17124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
17224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
17324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void onLayoutOrientationChanged(boolean isLandscape) {
17424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Do nothing.
17524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
17624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
17724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
17824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public void hardResetSettings(SettingsManager settingsManager) {
17924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        // Do nothing.
18024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
18124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
18224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
18324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public HardwareSpec getHardwareSpec() {
1848c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu        /**
1858c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         * Instead of passively providing CameraAppUI the hardware spec here,
1868c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         * {@link com.android.camera.captureintent.state.StateOpeningCamera}
1878c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         * will actively specify hardware spec.
1888c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         */
1898c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu        return null;
19024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
19124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
19224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
19324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public CameraAppUI.BottomBarUISpec getBottomBarSpec() {
1948c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu        /**
1958c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         * Instead of passively providing CameraAppUI the bottom bar spec here,
1968c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         * {@link com.android.camera.captureintent.state.StateOpeningCamera}
1978c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         * will actively specify bottom bar spec.
1988c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu         */
1998c50948fce260d0614daed71fc53ca5bf0e98060Senpo Hu        return null;
20024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
20124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
20224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
20324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public boolean isUsingBottomBar() {
20424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return true;
20524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
20624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
20724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
20824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public String getPeekAccessibilityString() {
209cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu        return mResourceConstructed.get().getContext().getResources()
210cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu                .getString(R.string.photo_accessibility_peek);
21124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
21224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
21324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
21424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public boolean onKeyDown(int keyCode, KeyEvent event) {
215edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        switch (keyCode) {
216edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            case KeyEvent.KEYCODE_CAMERA:
217edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            case KeyEvent.KEYCODE_DPAD_CENTER:
218edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                mStateMachine.processEvent(new EventClickOnCameraKey());
219edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                return true;
220edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            case KeyEvent.KEYCODE_VOLUME_UP:
221edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            case KeyEvent.KEYCODE_VOLUME_DOWN:
222edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                // Prevent default.
223edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                return true;
224edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        }
22524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return false;
22624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
22724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
22824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    @Override
22924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    public boolean onKeyUp(int keyCode, KeyEvent event) {
230edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        switch (keyCode) {
231edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            case KeyEvent.KEYCODE_VOLUME_UP:
232edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu            case KeyEvent.KEYCODE_VOLUME_DOWN:
233edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                mStateMachine.processEvent(new EventClickOnCameraKey());
234edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu                return true;
235edd5f8086326786390a7c74dda3f0a6c9ba933b5Senpo Hu        }
23624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        return false;
23724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    }
23824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
23924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    /** The listener to listen events from the UI. */
24024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final CaptureIntentModuleUI.Listener mUIListener =
24124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            new CaptureIntentModuleUI.Listener() {
24224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                @Override
24324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                public void onZoomRatioChanged(final float zoomRatio) {
2441b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                    mStateMachine.processEvent(new EventZoomRatioChanged(zoomRatio));
24524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                }
24624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            };
24724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
24824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    /** The listener to listen events from the preview. */
24924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    private final PreviewStatusListener mPreviewStatusListener = new PreviewStatusListener() {
25024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
25124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public void onPreviewLayoutChanged(View v, int left, int top, int right,
25224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
25324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            final Size previewLayoutSize = new Size(right - left, bottom - top);
2541b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            mStateMachine.processEvent(new EventOnTextureViewLayoutChanged(previewLayoutSize));
25524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
25624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
25724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
25824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public boolean shouldAutoAdjustTransformMatrixOnLayout() {
259cc6139467c1c9545de1f098d938409e182c9b7adSenpo Hu            return CaptureIntentConfig.WORKAROUND_PREVIEW_STRETCH_BUG_NEXUS4;
26024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
26124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
26224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
26324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public void onPreviewFlipped() {
26424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            // Do nothing because when preview is flipped, TextureView will lay
26524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            // itself out again, which will then trigger a transform matrix
26624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            // update.
26724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
26824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
26924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
27024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public GestureDetector.OnGestureListener getGestureListener() {
27124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            return new GestureDetector.SimpleOnGestureListener() {
27224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                @Override
27324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                public boolean onSingleTapUp(MotionEvent ev) {
27424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                    final Point tapPoint = new Point((int) ev.getX(), (int) ev.getY());
2751b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu                    mStateMachine.processEvent(new EventTapOnPreview(tapPoint));
27624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                    return true;
27724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                }
27824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            };
27924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
28024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
28124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
28224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public View.OnTouchListener getTouchListener() {
28324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            return null;
28424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
28524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
28624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
28724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public void onSurfaceTextureAvailable(
28824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                final SurfaceTexture surfaceTexture, int width, int height) {
2891b98e83085e2b0a3066a4bf3cbde2d664b8422eeSenpo Hu            mStateMachine.processEvent(new EventOnSurfaceTextureAvailable(surfaceTexture));
29024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
29124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
29224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
29324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
294de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu            mStateMachine.processEvent(new EventOnSurfaceTextureDestroyed());
29524be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu            return true;
29624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
29724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
29824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
29924be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public void onSurfaceTextureSizeChanged(
30024be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu                SurfaceTexture surfaceTexture, int width, int height) {
30124be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
30224be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu
30324be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        @Override
30424be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
305de4e5225ea92d681f9f4c005e6285f739635d271Senpo Hu            mStateMachine.processEvent(new EventOnSurfaceTextureUpdated());
30624be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu        }
30724be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu    };
30824be7cc6d138129b4087ef28f114701de54aba3cSenpo Hu}
309