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
1978711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liuimport android.content.Context;
20d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.content.Intent;
21d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.content.res.Configuration;
22d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.graphics.drawable.Drawable;
23d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.os.Bundle;
24b20535012f5b54e5b3cfa9576c25996bb5f8b9f3Mangesh Ghiwareimport android.provider.MediaStore;
25d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.view.KeyEvent;
26bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liuimport android.view.LayoutInflater;
27d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.view.MotionEvent;
2878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liuimport android.view.OrientationEventListener;
29d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.view.View;
30bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liuimport android.view.ViewGroup;
31d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport android.widget.FrameLayout;
32d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
33d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbimport com.android.camera.ui.CameraSwitcher;
3420f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reckimport com.android.gallery3d.app.PhotoPage;
3554424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kongimport com.android.gallery3d.common.ApiHelper;
3657ce51c772ffd43341e442792b9894cb185ef237George Mountimport com.android.gallery3d.util.LightCycleHelper;
37d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
38d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolbpublic class CameraActivity extends ActivityBase
39d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        implements CameraSwitcher.CameraSwitchListener {
40b1be74d6833cd55429cc5c34885eddf613d08302Doris Liu    public static final int PHOTO_MODULE_INDEX = 0;
41b1be74d6833cd55429cc5c34885eddf613d08302Doris Liu    public static final int VIDEO_MODULE_INDEX = 1;
42cfbf201b06095591a2ae91af2aa4b97a9c4ae9a5George Mount    public static final int PANORAMA_MODULE_INDEX = 2;
43cfbf201b06095591a2ae91af2aa4b97a9c4ae9a5George Mount    public static final int LIGHTCYCLE_MODULE_INDEX = 3;
44b20535012f5b54e5b3cfa9576c25996bb5f8b9f3Mangesh Ghiware
45d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    CameraModule mCurrentModule;
46d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private FrameLayout mFrame;
47d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private ShutterButton mShutter;
48d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private CameraSwitcher mSwitcher;
49a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    private View mShutterSwitcher;
50d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb    private View mControlsBackground;
51d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private Drawable[] mDrawables;
52a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    private int mCurrentModuleIndex;
53a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    private MotionEvent mDown;
54d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
5578711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    private MyOrientationEventListener mOrientationListener;
5678711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    // The degrees of the device rotated clockwise from its natural orientation.
578eae48b01cab6dc63ba03ebf54bf95a20d3f293eYour Name    private int mLastRawOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
5878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu
59d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private static final String TAG = "CAM_activity";
60d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
61d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private static final int[] DRAW_IDS = {
62fdb79c492940d46b27702b0be71903f99af7e34fMichael Kolb            R.drawable.ic_switch_camera,
63b1be74d6833cd55429cc5c34885eddf613d08302Doris Liu            R.drawable.ic_switch_video,
64fdb79c492940d46b27702b0be71903f99af7e34fMichael Kolb            R.drawable.ic_switch_pan,
65ebf2df0f2696dd287a8235cf4e7c1cac0103a3deMichael Kolb            R.drawable.ic_switch_photosphere
66d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    };
67d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
6800fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mount    @Override
69d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onCreate(Bundle state) {
70d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onCreate(state);
71d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        setContentView(R.layout.camera_main);
7254424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong        mFrame = (FrameLayout) findViewById(R.id.main_content);
73d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mDrawables = new Drawable[DRAW_IDS.length];
74d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        for (int i = 0; i < DRAW_IDS.length; i++) {
75bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            mDrawables[i] = getResources().getDrawable(DRAW_IDS[i]);
76d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
77bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        init();
78bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
79bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu                || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
80bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            mCurrentModule = new VideoModule();
81a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            mCurrentModuleIndex = VIDEO_MODULE_INDEX;
82bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        } else {
83bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            mCurrentModule = new PhotoModule();
84a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            mCurrentModuleIndex = PHOTO_MODULE_INDEX;
85bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        }
86bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        mCurrentModule.init(this, mFrame, true);
87a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        mSwitcher.setCurrentIndex(mCurrentModuleIndex);
8878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        mOrientationListener = new MyOrientationEventListener(this);
89bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu    }
90bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
919713c56dfe1c298ab0c2c75d324dc69395d1c809Michael Kolb    public void init() {
92d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb        mControlsBackground = findViewById(R.id.controls);
93a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        mShutterSwitcher = findViewById(R.id.camera_shutter_switcher);
94bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        mShutter = (ShutterButton) findViewById(R.id.shutter_button);
95bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        mSwitcher = (CameraSwitcher) findViewById(R.id.camera_switcher);
9654424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong        int totaldrawid = (LightCycleHelper.hasLightCycleCapture(this)
9754424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                                ? DRAW_IDS.length : DRAW_IDS.length - 1);
9854424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong        if (!ApiHelper.HAS_OLD_PANORAMA) totaldrawid--;
9954424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong
10054424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong        int[] drawids = new int[totaldrawid];
10154424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong        int[] moduleids = new int[totaldrawid];
102a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        int ix = 0;
103d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        for (int i = 0; i < mDrawables.length; i++) {
10454424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong            if (i == PANORAMA_MODULE_INDEX && !ApiHelper.HAS_OLD_PANORAMA) {
10554424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                continue; // not enabled, so don't add to UI
10654424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong            }
107b20535012f5b54e5b3cfa9576c25996bb5f8b9f3Mangesh Ghiware            if (i == LIGHTCYCLE_MODULE_INDEX && !LightCycleHelper.hasLightCycleCapture(this)) {
10800fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mount                continue; // not enabled, so don't add to UI
10900fea1c7ee987877f7218bfb9a217f4b7f0e90e4George Mount            }
11054424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong            moduleids[ix] = i;
111a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            drawids[ix++] = DRAW_IDS[i];
112a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        }
11354424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong        mSwitcher.setIds(moduleids, drawids);
114032dea1d8406cde556ec0a441e4c90409edf9d63John Reck        mSwitcher.setSwitchListener(this);
115032dea1d8406cde556ec0a441e4c90409edf9d63John Reck        mSwitcher.setCurrentIndex(mCurrentModuleIndex);
116a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb    }
117a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb
11878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    private class MyOrientationEventListener
11978711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            extends OrientationEventListener {
12078711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        public MyOrientationEventListener(Context context) {
12178711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            super(context);
12278711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        }
12378711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu
12478711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        @Override
12578711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        public void onOrientationChanged(int orientation) {
12678711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            // We keep the last known orientation. So if the user first orient
12778711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            // the camera then point the camera to floor or sky, we still have
12878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            // the correct orientation.
12978711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            if (orientation == ORIENTATION_UNKNOWN) return;
1308eae48b01cab6dc63ba03ebf54bf95a20d3f293eYour Name            mLastRawOrientation = orientation;
13178711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu            mCurrentModule.onOrientationChanged(orientation);
13278711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        }
13378711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu    }
134d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
135d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
136943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck    public void onCameraSelected(int i) {
1376f236b17ab7f0dbf2f8fe8251186410a8e76311cChih-Chung Chang        if (mPaused) return;
138a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if (i != mCurrentModuleIndex) {
139d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            mPaused = true;
140943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck            boolean canReuse = canReuseScreenNail();
141943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck            CameraHolder.instance().keep();
142943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck            closeModule(mCurrentModule);
143943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck            mCurrentModuleIndex = i;
144943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck            switch (i) {
145943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                case VIDEO_MODULE_INDEX:
146943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    mCurrentModule = new VideoModule();
147943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    break;
148943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                case PHOTO_MODULE_INDEX:
149943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    mCurrentModule = new PhotoModule();
150943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    break;
151943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                case PANORAMA_MODULE_INDEX:
152943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    mCurrentModule = new PanoramaModule();
153943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    break;
154943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                case LIGHTCYCLE_MODULE_INDEX:
155943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    mCurrentModule = LightCycleHelper.createPanoramaModule();
156943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck                    break;
157d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            }
158943f43f2bf0c58a8e9003dd5100cf9a39670dfd2John Reck            openModule(mCurrentModule, canReuse);
159fe53ae0fb40c05ca540f500597b68939311eff1cYour Name            mCurrentModule.onOrientationChanged(mLastRawOrientation);
160d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
161d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
162d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
163561af39348f34db4d67bc954536d6f6cbf296054John Reck    @Override
164561af39348f34db4d67bc954536d6f6cbf296054John Reck    public void onShowSwitcherPopup() {
165561af39348f34db4d67bc954536d6f6cbf296054John Reck        mCurrentModule.onShowSwitcherPopup();
166561af39348f34db4d67bc954536d6f6cbf296054John Reck    }
167561af39348f34db4d67bc954536d6f6cbf296054John Reck
168b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck    private void openModule(CameraModule module, boolean canReuse) {
169b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck        module.init(this, mFrame, canReuse && canReuseScreenNail());
170d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mPaused = false;
171d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onResumeBeforeSuper();
172d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onResumeAfterSuper();
173d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
174d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
175d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    private void closeModule(CameraModule module) {
176d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onPauseBeforeSuper();
177d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        module.onPauseAfterSuper();
178d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mFrame.removeAllViews();
179d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
180d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
181d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public ShutterButton getShutterButton() {
182d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mShutter;
183d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
184d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
185b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void hideUI() {
186d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb        mControlsBackground.setVisibility(View.INVISIBLE);
18790ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        hideSwitcher();
188ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb        mShutter.setVisibility(View.GONE);
189b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
190b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
191b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    public void showUI() {
192d200be24670fe4e455abeef0e684af6370f85a79Michael Kolb        mControlsBackground.setVisibility(View.VISIBLE);
19390ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        showSwitcher();
194b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb        mShutter.setVisibility(View.VISIBLE);
19545df1bd45d714decb63ae69c98116c75184459f9Doris Liu        // Force a layout change to show shutter button
19645df1bd45d714decb63ae69c98116c75184459f9Doris Liu        mShutter.requestLayout();
197b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb    }
198b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb
199da04f24a205d92c72c32d7768f0d3b4b1f93512dMichael Kolb    public void hideSwitcher() {
200b8317ef78fa41224a0a8d43431c3eac8e10772f1George Mount        mSwitcher.closePopup();
201b8317ef78fa41224a0a8d43431c3eac8e10772f1George Mount        mSwitcher.setVisibility(View.INVISIBLE);
202ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    }
203ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb
204ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    public void showSwitcher() {
20590ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        if (mCurrentModule.needsSwitcher()) {
20690ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb            mSwitcher.setVisibility(View.VISIBLE);
20790ef46f0248437fbcb2c80c8a65239f4da32b039Michael Kolb        }
208ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    }
209ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb
210812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb    public boolean isInCameraApp() {
211812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb        return mShowCameraAppView;
212812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb    }
213812fcbcb099b5ff7b9f9ae8bb4219d57dc29c70cMichael Kolb
214d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
215d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onConfigurationChanged(Configuration config) {
216d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onConfigurationChanged(config);
217bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
218bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        ViewGroup appRoot = (ViewGroup) findViewById(R.id.content);
219bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        // remove old switcher, shutter and shutter icon
220bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        View cameraControlsView = findViewById(R.id.camera_shutter_switcher);
221bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        appRoot.removeView(cameraControlsView);
222bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
223bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        // create new layout with the current orientation
224bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        LayoutInflater inflater = getLayoutInflater();
225bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        inflater.inflate(R.layout.camera_shutter_switcher, appRoot);
226bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        init();
227bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu
228bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        if (mShowCameraAppView) {
229bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            showUI();
230bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        } else {
231bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu            hideUI();
232bcaf81f9e730309f8a07d02d130b431eb036a1b3Doris Liu        }
233d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onConfigurationChanged(config);
234d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
235d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
236d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
237d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onPause() {
238d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mPaused = true;
23978711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        mOrientationListener.disable();
240d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onPauseBeforeSuper();
241d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onPause();
242d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onPauseAfterSuper();
243d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
244d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
245d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
246d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onResume() {
247d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mPaused = false;
24878711c990e57ce7c6228c5446cfb6902f2a47cb6Doris Liu        mOrientationListener.enable();
249d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onResumeBeforeSuper();
250d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onResume();
251d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onResumeAfterSuper();
252d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
253d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
254d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
255d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onFullScreenChanged(boolean full) {
256ad2031cd71422115983bccef779851debc9d47dcMichael Kolb        if (full) {
257ad2031cd71422115983bccef779851debc9d47dcMichael Kolb            showUI();
258ad2031cd71422115983bccef779851debc9d47dcMichael Kolb        } else {
259ad2031cd71422115983bccef779851debc9d47dcMichael Kolb            hideUI();
260ad2031cd71422115983bccef779851debc9d47dcMichael Kolb        }
261d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onFullScreenChanged(full);
262d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onFullScreenChanged(full);
263d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
264d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
265d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
266d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onStop() {
267d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onStop();
268d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onStop();
269dff2ace04b640fa8103dda8d1c4074c7d5affed8Doris Liu        getStateManager().clearTasks();
270d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
271d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
272d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
273d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onNewIntent(Intent intent) {
274d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onNewIntent(intent);
275d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        getStateManager().clearActivityResult();
276d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
277d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
278d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
279d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void installIntentFilter() {
280d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.installIntentFilter();
281d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.installIntentFilter();
282d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
283d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
284d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
285d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onActivityResult(
286d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            int requestCode, int resultCode, Intent data) {
28720f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        // Only PhotoPage understands ProxyLauncher.RESULT_USER_CANCELED
28820f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        if (resultCode == ProxyLauncher.RESULT_USER_CANCELED
28920f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck                && !(getStateManager().getTopState() instanceof PhotoPage)) {
29020f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck            resultCode = RESULT_CANCELED;
29120f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        }
292d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onActivityResult(requestCode, resultCode, data);
29320f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        // Unmap cancel vs. reset
29420f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        if (resultCode == ProxyLauncher.RESULT_USER_CANCELED) {
29520f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck            resultCode = RESULT_CANCELED;
29620f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        }
297d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onActivityResult(requestCode, resultCode, data);
298d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
299d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
300d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // Preview area is touched. Handle touch focus.
301d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
302d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected void onSingleTapUp(View view, int x, int y) {
303d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onSingleTapUp(view, x, y);
304d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
305d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
306d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
307d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onBackPressed() {
308d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        if (!mCurrentModule.onBackPressed()) {
309d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb            super.onBackPressed();
310d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        }
311d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
312d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
313d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
314d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public boolean onKeyDown(int keyCode, KeyEvent event) {
315d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mCurrentModule.onKeyDown(keyCode,  event)
316d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb                || super.onKeyDown(keyCode, event);
317d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
318d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
319d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
320d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public boolean onKeyUp(int keyCode, KeyEvent event) {
321d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mCurrentModule.onKeyUp(keyCode,  event)
322d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb                || super.onKeyUp(keyCode, event);
323d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
324d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
3259f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb    public void cancelActivityTouchHandling() {
326a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if (mDown != null) {
327a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            MotionEvent cancel = MotionEvent.obtain(mDown);
328a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            cancel.setAction(MotionEvent.ACTION_CANCEL);
329a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            super.dispatchTouchEvent(cancel);
3309f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb        }
3319f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb    }
3329f8b479c44e8fafda688ac0fab9882584a94d55fMichael Kolb
333d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
334d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public boolean dispatchTouchEvent(MotionEvent m) {
335a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if (m.getActionMasked() == MotionEvent.ACTION_DOWN) {
336a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            mDown = m;
337a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        }
338a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        if ((mSwitcher != null) && mSwitcher.showsPopup() && !mSwitcher.isInsidePopup(m)) {
339a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            return mSwitcher.onTouch(null, m);
340a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb        } else {
341a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb            return mShutterSwitcher.dispatchTouchEvent(m)
342a5e23d9eb2bc96e7da4c021df2e11c1c43d379cdMichael Kolb                    || mCurrentModule.dispatchTouchEvent(m);
343566f11c903ceae2e53c645f8d630bb1331faf890Michael Kolb        }
3444d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
3454d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
34620f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck    @Override
34720f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck    public void startActivityForResult(Intent intent, int requestCode) {
34820f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        Intent proxyIntent = new Intent(this, ProxyLauncher.class);
34920f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        proxyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
35020f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        proxyIntent.putExtra(Intent.EXTRA_INTENT, intent);
35120f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck        super.startActivityForResult(proxyIntent, requestCode);
35220f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck    }
35320f8a92e29e5edb414fae43f87c2c6890ea8fc84John Reck
3544d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public boolean superDispatchTouchEvent(MotionEvent m) {
3554d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        return super.dispatchTouchEvent(m);
3567114364044191d10505145df38d406cbb63dcdbaMichael Kolb    }
3577114364044191d10505145df38d406cbb63dcdbaMichael Kolb
358d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // Preview texture has been copied. Now camera can be released and the
359d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    // animation can be started.
360d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
361d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onPreviewTextureCopied() {
362d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onPreviewTextureCopied();
363d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
364d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
365d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
366d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    public void onCaptureTextureCopied() {
367d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount        mCurrentModule.onCaptureTextureCopied();
368d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    }
369d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount
370d282a28c60ca8f4ee82d519b12e8b0b057b294d4George Mount    @Override
371d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void onUserInteraction() {
372d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.onUserInteraction();
373d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.onUserInteraction();
374d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
375d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
376d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
377d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    protected boolean updateStorageHintOnResume() {
378d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        return mCurrentModule.updateStorageHintOnResume();
379d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
380d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
381d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    @Override
382d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    public void updateCameraAppView() {
383d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        super.updateCameraAppView();
384d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb        mCurrentModule.updateCameraAppView();
385d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb    }
386d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb
387b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck    private boolean canReuseScreenNail() {
388b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck        return mCurrentModuleIndex == PHOTO_MODULE_INDEX
38957ce51c772ffd43341e442792b9894cb185ef237George Mount                || mCurrentModuleIndex == VIDEO_MODULE_INDEX
39057ce51c772ffd43341e442792b9894cb185ef237George Mount                || mCurrentModuleIndex == LIGHTCYCLE_MODULE_INDEX;
391b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck    }
392b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck
393ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    @Override
394ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    public boolean isPanoramaActivity() {
395b662638bf3d3a3edde4f21d0e4cf55a3d416656eJohn Reck        return (mCurrentModuleIndex == PANORAMA_MODULE_INDEX);
396ce1d8396924bf4ca9be076cfdf9594c4d33ebd9bMichael Kolb    }
397806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
398806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    // Accessor methods for getting latency times used in performance testing
399806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getAutoFocusTime() {
400806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
40154424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
402806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
403806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
404806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getShutterLag() {
405806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
40654424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                ((PhotoModule) mCurrentModule).mShutterLag : -1;
407806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
408806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
409806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getShutterToPictureDisplayedTime() {
410806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
41154424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
412806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
413806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
414806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getPictureDisplayedToJpegCallbackTime() {
415806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
41654424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
417806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
418806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
419806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getJpegCallbackFinishTime() {
420806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
42154424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
422806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
423806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi
424806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    public long getCaptureStartTime() {
425806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi        return (mCurrentModule instanceof PhotoModule) ?
42654424d9c722b6d40be2eb50ae24e6d8dd17ddcabAngus Kong                ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
427806e575a804e02ca0861c4b28a50887e54830592Jason Noguchi    }
42841d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb
429ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li    public boolean isRecording() {
430ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li        return (mCurrentModule instanceof VideoModule) ?
431ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li                ((VideoModule) mCurrentModule).isRecording() : false;
432ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li    }
433ed19156e705efb982b351653a3ea9b15f5a08df7Wu-cheng Li
43441d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb    public CameraScreenNail getCameraScreenNail() {
43541d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb        return (CameraScreenNail) mCameraScreenNail;
43641d49f0fa2c9c93869bacfd6e7f76299f482e40fMichael Kolb    }
437d3a252bb71d119cbaeff55aeaa27dd1f8adadba2Michael Kolb}
438