summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/CameraActivity.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/CameraActivity.java')
-rw-r--r--src/com/android/camera/CameraActivity.java437
1 files changed, 437 insertions, 0 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
new file mode 100644
index 000000000..d79832b7d
--- /dev/null
+++ b/src/com/android/camera/CameraActivity.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.OrientationEventListener;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.camera.ui.CameraSwitcher;
+import com.android.gallery3d.app.PhotoPage;
+import com.android.gallery3d.common.ApiHelper;
+import com.android.gallery3d.util.LightCycleHelper;
+
+public class CameraActivity extends ActivityBase
+ implements CameraSwitcher.CameraSwitchListener {
+ public static final int PHOTO_MODULE_INDEX = 0;
+ public static final int VIDEO_MODULE_INDEX = 1;
+ public static final int PANORAMA_MODULE_INDEX = 2;
+ public static final int LIGHTCYCLE_MODULE_INDEX = 3;
+
+ CameraModule mCurrentModule;
+ private FrameLayout mFrame;
+ private ShutterButton mShutter;
+ private CameraSwitcher mSwitcher;
+ private View mShutterSwitcher;
+ private View mControlsBackground;
+ private Drawable[] mDrawables;
+ private int mCurrentModuleIndex;
+ private MotionEvent mDown;
+
+ private MyOrientationEventListener mOrientationListener;
+ // The degrees of the device rotated clockwise from its natural orientation.
+ private int mLastRawOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
+
+ private static final String TAG = "CAM_activity";
+
+ private static final int[] DRAW_IDS = {
+ R.drawable.ic_switch_camera,
+ R.drawable.ic_switch_video,
+ R.drawable.ic_switch_pan,
+ R.drawable.ic_switch_photosphere
+ };
+
+ @Override
+ public void onCreate(Bundle state) {
+ super.onCreate(state);
+ setContentView(R.layout.camera_main);
+ mFrame = (FrameLayout) findViewById(R.id.main_content);
+ mDrawables = new Drawable[DRAW_IDS.length];
+ for (int i = 0; i < DRAW_IDS.length; i++) {
+ mDrawables[i] = getResources().getDrawable(DRAW_IDS[i]);
+ }
+ init();
+ if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction())
+ || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) {
+ mCurrentModule = new VideoModule();
+ mCurrentModuleIndex = VIDEO_MODULE_INDEX;
+ } else {
+ mCurrentModule = new PhotoModule();
+ mCurrentModuleIndex = PHOTO_MODULE_INDEX;
+ }
+ mCurrentModule.init(this, mFrame, true);
+ mSwitcher.setCurrentIndex(mCurrentModuleIndex);
+ mOrientationListener = new MyOrientationEventListener(this);
+ }
+
+ public void init() {
+ mControlsBackground = findViewById(R.id.controls);
+ mShutterSwitcher = findViewById(R.id.camera_shutter_switcher);
+ mShutter = (ShutterButton) findViewById(R.id.shutter_button);
+ mSwitcher = (CameraSwitcher) findViewById(R.id.camera_switcher);
+ int totaldrawid = (LightCycleHelper.hasLightCycleCapture(this)
+ ? DRAW_IDS.length : DRAW_IDS.length - 1);
+ if (!ApiHelper.HAS_OLD_PANORAMA) totaldrawid--;
+
+ int[] drawids = new int[totaldrawid];
+ int[] moduleids = new int[totaldrawid];
+ int ix = 0;
+ for (int i = 0; i < mDrawables.length; i++) {
+ if (i == PANORAMA_MODULE_INDEX && !ApiHelper.HAS_OLD_PANORAMA) {
+ continue; // not enabled, so don't add to UI
+ }
+ if (i == LIGHTCYCLE_MODULE_INDEX && !LightCycleHelper.hasLightCycleCapture(this)) {
+ continue; // not enabled, so don't add to UI
+ }
+ moduleids[ix] = i;
+ drawids[ix++] = DRAW_IDS[i];
+ }
+ mSwitcher.setIds(moduleids, drawids);
+ mSwitcher.setSwitchListener(this);
+ mSwitcher.setCurrentIndex(mCurrentModuleIndex);
+ }
+
+ private class MyOrientationEventListener
+ extends OrientationEventListener {
+ public MyOrientationEventListener(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onOrientationChanged(int orientation) {
+ // We keep the last known orientation. So if the user first orient
+ // the camera then point the camera to floor or sky, we still have
+ // the correct orientation.
+ if (orientation == ORIENTATION_UNKNOWN) return;
+ mLastRawOrientation = orientation;
+ mCurrentModule.onOrientationChanged(orientation);
+ }
+ }
+
+ @Override
+ public void onCameraSelected(int i) {
+ if (mPaused) return;
+ if (i != mCurrentModuleIndex) {
+ mPaused = true;
+ boolean canReuse = canReuseScreenNail();
+ CameraHolder.instance().keep();
+ closeModule(mCurrentModule);
+ mCurrentModuleIndex = i;
+ switch (i) {
+ case VIDEO_MODULE_INDEX:
+ mCurrentModule = new VideoModule();
+ break;
+ case PHOTO_MODULE_INDEX:
+ mCurrentModule = new PhotoModule();
+ break;
+ case PANORAMA_MODULE_INDEX:
+ mCurrentModule = new PanoramaModule();
+ break;
+ case LIGHTCYCLE_MODULE_INDEX:
+ mCurrentModule = LightCycleHelper.createPanoramaModule();
+ break;
+ }
+ openModule(mCurrentModule, canReuse);
+ mCurrentModule.onOrientationChanged(mLastRawOrientation);
+ }
+ }
+
+ @Override
+ public void onShowSwitcherPopup() {
+ mCurrentModule.onShowSwitcherPopup();
+ }
+
+ private void openModule(CameraModule module, boolean canReuse) {
+ module.init(this, mFrame, canReuse && canReuseScreenNail());
+ mPaused = false;
+ module.onResumeBeforeSuper();
+ module.onResumeAfterSuper();
+ }
+
+ private void closeModule(CameraModule module) {
+ module.onPauseBeforeSuper();
+ module.onPauseAfterSuper();
+ mFrame.removeAllViews();
+ }
+
+ public ShutterButton getShutterButton() {
+ return mShutter;
+ }
+
+ public void hideUI() {
+ mControlsBackground.setVisibility(View.INVISIBLE);
+ hideSwitcher();
+ mShutter.setVisibility(View.GONE);
+ }
+
+ public void showUI() {
+ mControlsBackground.setVisibility(View.VISIBLE);
+ showSwitcher();
+ mShutter.setVisibility(View.VISIBLE);
+ // Force a layout change to show shutter button
+ mShutter.requestLayout();
+ }
+
+ public void hideSwitcher() {
+ mSwitcher.closePopup();
+ mSwitcher.setVisibility(View.INVISIBLE);
+ }
+
+ public void showSwitcher() {
+ if (mCurrentModule.needsSwitcher()) {
+ mSwitcher.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public boolean isInCameraApp() {
+ return mShowCameraAppView;
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration config) {
+ super.onConfigurationChanged(config);
+
+ ViewGroup appRoot = (ViewGroup) findViewById(R.id.content);
+ // remove old switcher, shutter and shutter icon
+ View cameraControlsView = findViewById(R.id.camera_shutter_switcher);
+ appRoot.removeView(cameraControlsView);
+
+ // create new layout with the current orientation
+ LayoutInflater inflater = getLayoutInflater();
+ inflater.inflate(R.layout.camera_shutter_switcher, appRoot);
+ init();
+
+ if (mShowCameraAppView) {
+ showUI();
+ } else {
+ hideUI();
+ }
+ mCurrentModule.onConfigurationChanged(config);
+ }
+
+ @Override
+ public void onPause() {
+ mPaused = true;
+ mOrientationListener.disable();
+ mCurrentModule.onPauseBeforeSuper();
+ super.onPause();
+ mCurrentModule.onPauseAfterSuper();
+ }
+
+ @Override
+ public void onResume() {
+ mPaused = false;
+ mOrientationListener.enable();
+ mCurrentModule.onResumeBeforeSuper();
+ super.onResume();
+ mCurrentModule.onResumeAfterSuper();
+ }
+
+ @Override
+ protected void onFullScreenChanged(boolean full) {
+ if (full) {
+ showUI();
+ } else {
+ hideUI();
+ }
+ super.onFullScreenChanged(full);
+ mCurrentModule.onFullScreenChanged(full);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mCurrentModule.onStop();
+ getStateManager().clearTasks();
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ getStateManager().clearActivityResult();
+ }
+
+ @Override
+ protected void installIntentFilter() {
+ super.installIntentFilter();
+ mCurrentModule.installIntentFilter();
+ }
+
+ @Override
+ protected void onActivityResult(
+ int requestCode, int resultCode, Intent data) {
+ // Only PhotoPage understands ProxyLauncher.RESULT_USER_CANCELED
+ if (resultCode == ProxyLauncher.RESULT_USER_CANCELED
+ && !(getStateManager().getTopState() instanceof PhotoPage)) {
+ resultCode = RESULT_CANCELED;
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ // Unmap cancel vs. reset
+ if (resultCode == ProxyLauncher.RESULT_USER_CANCELED) {
+ resultCode = RESULT_CANCELED;
+ }
+ mCurrentModule.onActivityResult(requestCode, resultCode, data);
+ }
+
+ // Preview area is touched. Handle touch focus.
+ @Override
+ protected void onSingleTapUp(View view, int x, int y) {
+ mCurrentModule.onSingleTapUp(view, x, y);
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (!mCurrentModule.onBackPressed()) {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return mCurrentModule.onKeyDown(keyCode, event)
+ || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return mCurrentModule.onKeyUp(keyCode, event)
+ || super.onKeyUp(keyCode, event);
+ }
+
+ public void cancelActivityTouchHandling() {
+ if (mDown != null) {
+ MotionEvent cancel = MotionEvent.obtain(mDown);
+ cancel.setAction(MotionEvent.ACTION_CANCEL);
+ super.dispatchTouchEvent(cancel);
+ }
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent m) {
+ if (m.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mDown = m;
+ }
+ if ((mSwitcher != null) && mSwitcher.showsPopup() && !mSwitcher.isInsidePopup(m)) {
+ return mSwitcher.onTouch(null, m);
+ } else {
+ return mShutterSwitcher.dispatchTouchEvent(m)
+ || mCurrentModule.dispatchTouchEvent(m);
+ }
+ }
+
+ @Override
+ public void startActivityForResult(Intent intent, int requestCode) {
+ Intent proxyIntent = new Intent(this, ProxyLauncher.class);
+ proxyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ proxyIntent.putExtra(Intent.EXTRA_INTENT, intent);
+ super.startActivityForResult(proxyIntent, requestCode);
+ }
+
+ public boolean superDispatchTouchEvent(MotionEvent m) {
+ return super.dispatchTouchEvent(m);
+ }
+
+ // Preview texture has been copied. Now camera can be released and the
+ // animation can be started.
+ @Override
+ public void onPreviewTextureCopied() {
+ mCurrentModule.onPreviewTextureCopied();
+ }
+
+ @Override
+ public void onCaptureTextureCopied() {
+ mCurrentModule.onCaptureTextureCopied();
+ }
+
+ @Override
+ public void onUserInteraction() {
+ super.onUserInteraction();
+ mCurrentModule.onUserInteraction();
+ }
+
+ @Override
+ protected boolean updateStorageHintOnResume() {
+ return mCurrentModule.updateStorageHintOnResume();
+ }
+
+ @Override
+ public void updateCameraAppView() {
+ super.updateCameraAppView();
+ mCurrentModule.updateCameraAppView();
+ }
+
+ private boolean canReuseScreenNail() {
+ return mCurrentModuleIndex == PHOTO_MODULE_INDEX
+ || mCurrentModuleIndex == VIDEO_MODULE_INDEX
+ || mCurrentModuleIndex == LIGHTCYCLE_MODULE_INDEX;
+ }
+
+ @Override
+ public boolean isPanoramaActivity() {
+ return (mCurrentModuleIndex == PANORAMA_MODULE_INDEX);
+ }
+
+ // Accessor methods for getting latency times used in performance testing
+ public long getAutoFocusTime() {
+ return (mCurrentModule instanceof PhotoModule) ?
+ ((PhotoModule) mCurrentModule).mAutoFocusTime : -1;
+ }
+
+ public long getShutterLag() {
+ return (mCurrentModule instanceof PhotoModule) ?
+ ((PhotoModule) mCurrentModule).mShutterLag : -1;
+ }
+
+ public long getShutterToPictureDisplayedTime() {
+ return (mCurrentModule instanceof PhotoModule) ?
+ ((PhotoModule) mCurrentModule).mShutterToPictureDisplayedTime : -1;
+ }
+
+ public long getPictureDisplayedToJpegCallbackTime() {
+ return (mCurrentModule instanceof PhotoModule) ?
+ ((PhotoModule) mCurrentModule).mPictureDisplayedToJpegCallbackTime : -1;
+ }
+
+ public long getJpegCallbackFinishTime() {
+ return (mCurrentModule instanceof PhotoModule) ?
+ ((PhotoModule) mCurrentModule).mJpegCallbackFinishTime : -1;
+ }
+
+ public long getCaptureStartTime() {
+ return (mCurrentModule instanceof PhotoModule) ?
+ ((PhotoModule) mCurrentModule).mCaptureStartTime : -1;
+ }
+
+ public boolean isRecording() {
+ return (mCurrentModule instanceof VideoModule) ?
+ ((VideoModule) mCurrentModule).isRecording() : false;
+ }
+
+ public CameraScreenNail getCameraScreenNail() {
+ return (CameraScreenNail) mCameraScreenNail;
+ }
+}