CameraActivity.java revision 8eae48b01cab6dc63ba03ebf54bf95a20d3f293e
1d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb/*
2d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * Copyright (C) 2012 The Android Open Source Project
3d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb *
4d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
5d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * you may not use this file except in compliance with the License.
6d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * You may obtain a copy of the License at
7d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb *
8d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
9d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb *
10d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * Unless required by applicable law or agreed to in writing, software
11d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
12d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * See the License for the specific language governing permissions and
14d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb * limitations under the License.
15d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb */
16d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
17d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbpackage com.android.camera;
18d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
193e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reckimport android.animation.Animator;
203e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reckimport android.animation.AnimatorListenerAdapter;
213e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reckimport android.animation.ObjectAnimator;
2278711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liuimport android.content.Context;
23d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.content.Intent;
24d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.content.res.Configuration;
25d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.graphics.drawable.Drawable;
26d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.os.Bundle;
27b20535012f5b54e5b3cfa9576c25996bb5f8b9f3Mangesh Ghiwareimport android.provider.MediaStore;
28d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.view.KeyEvent;
29bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liuimport android.view.LayoutInflater;
30d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.view.MotionEvent;
3178711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liuimport android.view.OrientationEventListener;
32d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.view.View;
33bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liuimport android.view.ViewGroup;
34d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.widget.FrameLayout;
35d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
36d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport com.android.camera.ui.CameraSwitcher;
3720f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reckimport com.android.gallery3d.app.PhotoPage;
3800fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mountimport com.android.gallery3d.util.LightCycleHelper;
39d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
40d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbpublic class CameraActivity extends ActivityBase
41d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        implements CameraSwitcher.CameraSwitchListener {
42b1be74d6833cd55429cc5c34885eddf613d08302Doris Liu    public static final int PHOTO_MODULE_INDEX = 0;
43b1be74d6833cd55429cc5c34885eddf613d08302Doris Liu    public static final int VIDEO_MODULE_INDEX = 1;
44cfbf201b06095591a2ae91af2aa4b97a9c4ae9a5George Mount    public static final int PANORAMA_MODULE_INDEX = 2;
45cfbf201b06095591a2ae91af2aa4b97a9c4ae9a5George Mount    public static final int LIGHTCYCLE_MODULE_INDEX = 3;
46b20535012f5b54e5b3cfa9576c25996bb5f8b9f3Mangesh Ghiware
47d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    CameraModule mCurrentModule;
48d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private FrameLayout mFrame;
49d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private ShutterButton mShutter;
50d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private CameraSwitcher mSwitcher;
51a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    private View mShutterSwitcher;
52d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb    private View mControlsBackground;
53d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private Drawable[] mDrawables;
54a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    private int mCurrentModuleIndex;
55a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    private MotionEvent mDown;
56d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
5778711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    private MyOrientationEventListener mOrientationListener;
5878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    // The degrees of the device rotated clockwise from its natural orientation.
598eae48b01cab6dc63ba03ebf54bf95a20d3f293eYour Name    private int mLastRawOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
6078711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu
61d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private static final String TAG = "CAM_activity";
62d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
63d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private static final int[] DRAW_IDS = {
64fdb79c492940d46b27702b0be71903f99af7e34fMichael Kolb            R.drawable.ic_switch_camera,
65b1be74d6833cd55429cc5c34885eddf613d08302Doris Liu            R.drawable.ic_switch_video,
66fdb79c492940d46b27702b0be71903f99af7e34fMichael Kolb            R.drawable.ic_switch_pan,
67ebf2df0f2696dd287a8235cf4e7c1cac0103a3deMichael Kolb            R.drawable.ic_switch_photosphere
68d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    };
69d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
7000fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mount    @Override
71d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onCreate(Bundle state) {
72d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onCreate(state);
73d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        setContentView(R.layout.camera_main);
74d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mFrame =(FrameLayout) findViewById(R.id.main_content);
75d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mDrawables = new Drawable[DRAW_IDS.length];
76d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        for (int i = 0; i < DRAW_IDS.length; i++) {
77bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            mDrawables[i] = getResources().getDrawable(DRAW_IDS[i]);
78d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
79bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        init();
80bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
81bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu                || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
82bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            mCurrentModule = new VideoModule();
83a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            mCurrentModuleIndex = VIDEO_MODULE_INDEX;
84bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        } else {
85bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            mCurrentModule = new PhotoModule();
86a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            mCurrentModuleIndex = PHOTO_MODULE_INDEX;
87bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        }
88bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        mCurrentModule.init(this, mFrame, true);
89a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        mSwitcher.setCurrentIndex(mCurrentModuleIndex);
9078711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        mOrientationListener = new MyOrientationEventListener(this);
91bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu    }
92bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
939713c56dfe1c298ab0c2c75d324dc69395d1c809Michael Kolb    public void init() {
94d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb        mControlsBackground = findViewById(R.id.controls);
95a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        mShutterSwitcher = findViewById(R.id.camera_shutter_switcher);
96bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        mShutter = (ShutterButton) findViewById(R.id.shutter_button);
97bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        mSwitcher = (CameraSwitcher) findViewById(R.id.camera_switcher);
98a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        mSwitcher.setDrawIds(DRAW_IDS);
99a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        int[] drawids = new int[LightCycleHelper.hasLightCycleCapture(this)
100a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb                                ? DRAW_IDS.length : DRAW_IDS.length - 1];
101a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        int ix = 0;
102d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        for (int i = 0; i < mDrawables.length; i++) {
103b20535012f5b54e5b3cfa9576c25996bb5f8b9f3Mangesh Ghiware            if (i == LIGHTCYCLE_MODULE_INDEX && !LightCycleHelper.hasLightCycleCapture(this)) {
10400fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mount                continue; // not enabled, so don't add to UI
10500fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mount            }
106a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            drawids[ix++] = DRAW_IDS[i];
107a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        }
108a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        mSwitcher.setDrawIds(drawids);
109032dea1d8406cde556ec0a441e4c90409edf9d63John Reck        mSwitcher.setSwitchListener(this);
110032dea1d8406cde556ec0a441e4c90409edf9d63John Reck        mSwitcher.setCurrentIndex(mCurrentModuleIndex);
111a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    }
112a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb
11378711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    private class MyOrientationEventListener
11478711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            extends OrientationEventListener {
11578711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        public MyOrientationEventListener(Context context) {
11678711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            super(context);
11778711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        }
11878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu
11978711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        @Override
12078711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        public void onOrientationChanged(int orientation) {
12178711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            // We keep the last known orientation. So if the user first orient
12278711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            // the camera then point the camera to floor or sky, we still have
12378711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            // the correct orientation.
12478711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            if (orientation == ORIENTATION_UNKNOWN) return;
1258eae48b01cab6dc63ba03ebf54bf95a20d3f293eYour Name            mLastRawOrientation = orientation;
12678711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            mCurrentModule.onOrientationChanged(orientation);
12778711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        }
12878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    }
129d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
1303e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    private ObjectAnimator mCameraSwitchAnimator;
1313e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
132d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
1333e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    public void onCameraSelected(final int i) {
1346f236b17ab7f0dbf2f8fe8251186410a8e76311cChih-Chung Chang        if (mPaused) return;
135a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if (i != mCurrentModuleIndex) {
136d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            mPaused = true;
1373e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            CameraScreenNail screenNail = getCameraScreenNail();
1383e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            if (screenNail != null) {
1393e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                if (mCameraSwitchAnimator != null && mCameraSwitchAnimator.isRunning()) {
1403e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                    mCameraSwitchAnimator.cancel();
1413e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                }
1423e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCameraSwitchAnimator = ObjectAnimator.ofFloat(
1433e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                        screenNail, "alpha", screenNail.getAlpha(), 0f);
1443e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCameraSwitchAnimator.addListener(new AnimatorListenerAdapter() {
1453e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                    @Override
1463e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                    public void onAnimationEnd(Animator animation) {
1473e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                        super.onAnimationEnd(animation);
1483e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                        doChangeCamera(i);
1493e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                    }
1503e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                });
1513e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCameraSwitchAnimator.start();
1523e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            } else {
1533e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                doChangeCamera(i);
154d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            }
1553e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
1563e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        }
1573e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    }
1583e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
1593e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    private void doChangeCamera(int i) {
1603e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        boolean canReuse = canReuseScreenNail();
1613e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        CameraHolder.instance().keep();
1623e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        closeModule(mCurrentModule);
1633e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        mCurrentModuleIndex = i;
1643e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        switch (i) {
1653e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            case VIDEO_MODULE_INDEX:
1663e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCurrentModule = new VideoModule();
1673e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                break;
1683e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            case PHOTO_MODULE_INDEX:
1693e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCurrentModule = new PhotoModule();
1703e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                break;
1713e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            case PANORAMA_MODULE_INDEX:
1723e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCurrentModule = new PanoramaModule();
1733e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                break;
1743e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            case LIGHTCYCLE_MODULE_INDEX:
1753e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                mCurrentModule = LightCycleHelper.createPanoramaModule();
1763e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                break;
177d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
1783e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        openModule(mCurrentModule, canReuse);
1798eae48b01cab6dc63ba03ebf54bf95a20d3f293eYour Name        mCurrentModule.onOrientationChanged(mLastRawOrientation);
1803e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        getCameraScreenNail().setAlpha(0f);
1813e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        getCameraScreenNail().setOnFrameDrawnOneShot(mOnFrameDrawn);
182d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
183d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
1843e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    private Runnable mOnFrameDrawn = new Runnable() {
1853e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
1863e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        @Override
1873e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        public void run() {
1883e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            runOnUiThread(mFadeInCameraScreenNail);
1893e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        }
1903e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    };
1913e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
1923e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    private Runnable mFadeInCameraScreenNail = new Runnable() {
1933e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
1943e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        @Override
1953e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        public void run() {
1963e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            mCameraSwitchAnimator = ObjectAnimator.ofFloat(
1973e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck                    getCameraScreenNail(), "alpha", 0f, 1f);
1983e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            mCameraSwitchAnimator.setStartDelay(50);
1993e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck            mCameraSwitchAnimator.start();
2003e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck        }
2013e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck    };
2023e40e8d8a2fecd360fb7fe339ec1c6044e4a70bcJohn Reck
203561af39348f34db4d67bc954536d6f6cbf296054John Reck    @Override
204561af39348f34db4d67bc954536d6f6cbf296054John Reck    public void onShowSwitcherPopup() {
205561af39348f34db4d67bc954536d6f6cbf296054John Reck        mCurrentModule.onShowSwitcherPopup();
206561af39348f34db4d67bc954536d6f6cbf296054John Reck    }
207561af39348f34db4d67bc954536d6f6cbf296054John Reck
208b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck    private void openModule(CameraModule module, boolean canReuse) {
209b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck        module.init(this, mFrame, canReuse && canReuseScreenNail());
210d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mPaused = false;
211d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onResumeBeforeSuper();
212d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onResumeAfterSuper();
213d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
214d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
215d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private void closeModule(CameraModule module) {
216d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onPauseBeforeSuper();
217d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onPauseAfterSuper();
218d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mFrame.removeAllViews();
219d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
220d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
221d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public ShutterButton getShutterButton() {
222d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mShutter;
223d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
224d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
225b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void hideUI() {
226d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb        mControlsBackground.setVisibility(View.INVISIBLE);
22790ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        hideSwitcher();
228ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb        mShutter.setVisibility(View.GONE);
229b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
230b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
231b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void showUI() {
232d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb        mControlsBackground.setVisibility(View.VISIBLE);
23390ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        showSwitcher();
234b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mShutter.setVisibility(View.VISIBLE);
23545df1bd45d714decb63ae69c98116c75184459f9Doris Liu        // Force a layout change to show shutter button
23645df1bd45d714decb63ae69c98116c75184459f9Doris Liu        mShutter.requestLayout();
237b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
238b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
239da04f24a205d92c72c32d7768f0d3b4b1f93512dMichael Kolb    public void hideSwitcher() {
240b8317ef78fa41224a0a8d43431c3eac8e10772f1George Mount        mSwitcher.closePopup();
241b8317ef78fa41224a0a8d43431c3eac8e10772f1George Mount        mSwitcher.setVisibility(View.INVISIBLE);
242ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    }
243ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb
244ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    public void showSwitcher() {
24590ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        if (mCurrentModule.needsSwitcher()) {
24690ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb            mSwitcher.setVisibility(View.VISIBLE);
24790ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        }
248ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    }
249ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb
250812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb    public boolean isInCameraApp() {
251812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb        return mShowCameraAppView;
252812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb    }
253812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb
254d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
255d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onConfigurationChanged(Configuration config) {
256d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onConfigurationChanged(config);
257bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
258bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        ViewGroup appRoot = (ViewGroup) findViewById(R.id.content);
259bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        // remove old switcher, shutter and shutter icon
260bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        View cameraControlsView = findViewById(R.id.camera_shutter_switcher);
261bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        appRoot.removeView(cameraControlsView);
262bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
263bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        // create new layout with the current orientation
264bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        LayoutInflater inflater = getLayoutInflater();
265bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        inflater.inflate(R.layout.camera_shutter_switcher, appRoot);
266bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        init();
267bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
268bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        if (mShowCameraAppView) {
269bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            showUI();
270bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        } else {
271bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            hideUI();
272bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        }
273d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onConfigurationChanged(config);
274d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
275d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
276d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
277d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onPause() {
278d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mPaused = true;
27978711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        mOrientationListener.disable();
280d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onPauseBeforeSuper();
281d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onPause();
282d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onPauseAfterSuper();
283d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
284d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
285d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
286d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onResume() {
287d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mPaused = false;
28878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        mOrientationListener.enable();
289d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onResumeBeforeSuper();
290d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onResume();
291d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onResumeAfterSuper();
292d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
293d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
294d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
295d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onFullScreenChanged(boolean full) {
296ad2031cd71422115983bccef779851debc9d47dcMichael Kolb        if (full) {
297ad2031cd71422115983bccef779851debc9d47dcMichael Kolb            showUI();
298ad2031cd71422115983bccef779851debc9d47dcMichael Kolb        } else {
299ad2031cd71422115983bccef779851debc9d47dcMichael Kolb            hideUI();
300ad2031cd71422115983bccef779851debc9d47dcMichael Kolb        }
301d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onFullScreenChanged(full);
302d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onFullScreenChanged(full);
303d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
304d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
305d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
306d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onStop() {
307d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onStop();
308d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onStop();
309dff2ace04b640fa8103dda8d1c4074c7d5affed8Doris Liu        getStateManager().clearTasks();
310d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
311d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
312d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
313d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onNewIntent(Intent intent) {
314d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onNewIntent(intent);
315d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        getStateManager().clearActivityResult();
316d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
317d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
318d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
319d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void installIntentFilter() {
320d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.installIntentFilter();
321d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.installIntentFilter();
322d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
323d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
324d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
325d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onActivityResult(
326d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            int requestCode, int resultCode, Intent data) {
32720f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        // Only PhotoPage understands ProxyLauncher.RESULT_USER_CANCELED
32820f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        if (resultCode == ProxyLauncher.RESULT_USER_CANCELED
32920f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck                && !(getStateManager().getTopState() instanceof PhotoPage)) {
33020f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck            resultCode = RESULT_CANCELED;
33120f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        }
332d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onActivityResult(requestCode, resultCode, data);
33320f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        // Unmap cancel vs. reset
33420f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        if (resultCode == ProxyLauncher.RESULT_USER_CANCELED) {
33520f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck            resultCode = RESULT_CANCELED;
33620f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        }
337d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onActivityResult(requestCode, resultCode, data);
338d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
339d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
340d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // Preview area is touched. Handle touch focus.
341d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
342d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onSingleTapUp(View view, int x, int y) {
343d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onSingleTapUp(view, x, y);
344d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
345d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
346d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
347d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onBackPressed() {
348d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        if (!mCurrentModule.onBackPressed()) {
349d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            super.onBackPressed();
350d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
351d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
352d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
353d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
354d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public boolean onKeyDown(int keyCode, KeyEvent event) {
355d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mCurrentModule.onKeyDown(keyCode,  event)
356d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb                || super.onKeyDown(keyCode, event);
357d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
358d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
359d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
360d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public boolean onKeyUp(int keyCode, KeyEvent event) {
361d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mCurrentModule.onKeyUp(keyCode,  event)
362d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb                || super.onKeyUp(keyCode, event);
363d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
364d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
3659f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb    public void cancelActivityTouchHandling() {
366a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if (mDown != null) {
367a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            MotionEvent cancel = MotionEvent.obtain(mDown);
368a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            cancel.setAction(MotionEvent.ACTION_CANCEL);
369a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            super.dispatchTouchEvent(cancel);
3709f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb        }
3719f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb    }
3729f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb
373d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
374d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public boolean dispatchTouchEvent(MotionEvent m) {
375a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if (m.getActionMasked() == MotionEvent.ACTION_DOWN) {
376a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            mDown = m;
377a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        }
378a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if ((mSwitcher != null) && mSwitcher.showsPopup() && !mSwitcher.isInsidePopup(m)) {
379a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            return mSwitcher.onTouch(null, m);
380a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        } else {
381a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            return mShutterSwitcher.dispatchTouchEvent(m)
382a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb                    || mCurrentModule.dispatchTouchEvent(m);
383566f11c903ceae2e53c645f8d630bb1331faf890Michael Kolb        }
3844d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
3854d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
38620f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck    @Override
38720f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck    public void startActivityForResult(Intent intent, int requestCode) {
38820f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        Intent proxyIntent = new Intent(this, ProxyLauncher.class);
38920f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        proxyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
39020f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        proxyIntent.putExtra(Intent.EXTRA_INTENT, intent);
39120f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        super.startActivityForResult(proxyIntent, requestCode);
39220f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck    }
39320f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck
3944d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public boolean superDispatchTouchEvent(MotionEvent m) {
3954d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        return super.dispatchTouchEvent(m);
3967114364044191d10505145df38d406cbb63dcdbaMichael Kolb    }
3977114364044191d10505145df38d406cbb63dcdbaMichael Kolb
398d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // Preview texture has been copied. Now camera can be released and the
399d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // animation can be started.
400d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
401d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onPreviewTextureCopied() {
402d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onPreviewTextureCopied();
403d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
404d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
405d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
406d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    public void onCaptureTextureCopied() {
407d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount        mCurrentModule.onCaptureTextureCopied();
408d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    }
409d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount
410d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    @Override
411d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onUserInteraction() {
412d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onUserInteraction();
413d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onUserInteraction();
414d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
415d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
416d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
417d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected boolean updateStorageHintOnResume() {
418d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mCurrentModule.updateStorageHintOnResume();
419d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
420d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
421d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
422d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void updateCameraAppView() {
423d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.updateCameraAppView();
424d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.updateCameraAppView();
425d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
426d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
427b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck    private boolean canReuseScreenNail() {
428b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck        return mCurrentModuleIndex == PHOTO_MODULE_INDEX
429b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck                || mCurrentModuleIndex == VIDEO_MODULE_INDEX;
430b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck    }
431b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck
432ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    @Override
433ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    public boolean isPanoramaActivity() {
434b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck        return (mCurrentModuleIndex == PANORAMA_MODULE_INDEX);
435ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    }
436806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
437806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    // Accessor methods for getting latency times used in performance testing
438806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getAutoFocusTime() {
439806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
440806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi                ((PhotoModule)mCurrentModule).mAutoFocusTime : -1;
441806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
442806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
443806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getShutterLag() {
444806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
445806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi                ((PhotoModule)mCurrentModule).mShutterLag : -1;
446806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
447806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
448806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getShutterToPictureDisplayedTime() {
449806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
450806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi                ((PhotoModule)mCurrentModule).mShutterToPictureDisplayedTime : -1;
451806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
452806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
453806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getPictureDisplayedToJpegCallbackTime() {
454806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
455806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi                ((PhotoModule)mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
456806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
457806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
458806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getJpegCallbackFinishTime() {
459806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
460806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi                ((PhotoModule)mCurrentModule).mJpegCallbackFinishTime : -1;
461806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
462806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
463806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getCaptureStartTime() {
464806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
465806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi                ((PhotoModule)mCurrentModule).mCaptureStartTime : -1;
466806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
46741d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb
468ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li    public boolean isRecording() {
469ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li        return (mCurrentModule instanceof VideoModule) ?
470ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li                ((VideoModule) mCurrentModule).isRecording() : false;
471ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li    }
472ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li
47341d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb    public CameraScreenNail getCameraScreenNail() {
47441d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb        return (CameraScreenNail) mCameraScreenNail;
47541d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb    }
476d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb}
477