summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/PhotoUI.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/PhotoUI.java')
-rw-r--r--src/com/android/camera/PhotoUI.java864
1 files changed, 864 insertions, 0 deletions
diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java
new file mode 100644
index 000000000..d58ed7f13
--- /dev/null
+++ b/src/com/android/camera/PhotoUI.java
@@ -0,0 +1,864 @@
+/*
+ * 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.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.graphics.Matrix;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.hardware.Camera.Face;
+import android.hardware.Camera.FaceDetectionListener;
+import android.hardware.Camera.Size;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.TextureView;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
+import android.view.ViewStub;
+import android.widget.FrameLayout;
+import android.widget.FrameLayout.LayoutParams;
+import android.widget.Toast;
+
+import com.android.camera.CameraPreference.OnPreferenceChangedListener;
+import com.android.camera.FocusOverlayManager.FocusUI;
+import com.android.camera.ui.AbstractSettingPopup;
+import com.android.camera.ui.CameraControls;
+import com.android.camera.ui.CameraRootView;
+import com.android.camera.ui.CameraSwitcher;
+import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
+import com.android.camera.ui.CountDownView;
+import com.android.camera.ui.CountDownView.OnCountDownFinishedListener;
+import com.android.camera.ui.FaceView;
+import com.android.camera.ui.FocusIndicator;
+import com.android.camera.ui.PieRenderer;
+import com.android.camera.ui.PieRenderer.PieListener;
+import com.android.camera.ui.RenderOverlay;
+import com.android.camera.ui.ZoomRenderer;
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.ApiHelper;
+
+import java.util.List;
+
+public class PhotoUI implements PieListener,
+ PreviewGestures.SingleTapListener,
+ FocusUI, TextureView.SurfaceTextureListener,
+ LocationManager.Listener, CameraRootView.MyDisplayListener,
+ CameraManager.CameraFaceDetectionCallback {
+
+ private static final String TAG = "CAM_UI";
+ private static final int UPDATE_TRANSFORM_MATRIX = 1;
+ private CameraActivity mActivity;
+ private PhotoController mController;
+ private PreviewGestures mGestures;
+
+ private View mRootView;
+ private Object mSurfaceTexture;
+
+ private AbstractSettingPopup mPopup;
+ private ShutterButton mShutterButton;
+ private CountDownView mCountDownView;
+
+ private FaceView mFaceView;
+ private RenderOverlay mRenderOverlay;
+ private View mReviewCancelButton;
+ private View mReviewDoneButton;
+ private View mReviewRetakeButton;
+
+ private View mMenuButton;
+ private View mBlocker;
+ private PhotoMenu mMenu;
+ private CameraSwitcher mSwitcher;
+ private CameraControls mCameraControls;
+ private AlertDialog mLocationDialog;
+
+ // Small indicators which show the camera settings in the viewfinder.
+ private OnScreenIndicators mOnScreenIndicators;
+
+ private PieRenderer mPieRenderer;
+ private ZoomRenderer mZoomRenderer;
+ private Toast mNotSelectableToast;
+
+ private int mZoomMax;
+ private List<Integer> mZoomRatios;
+
+ private int mPreviewWidth = 0;
+ private int mPreviewHeight = 0;
+ private float mSurfaceTextureUncroppedWidth;
+ private float mSurfaceTextureUncroppedHeight;
+
+ private View mPreviewThumb;
+ private ObjectAnimator mFlashAnim;
+ private View mFlashOverlay;
+
+ private SurfaceTextureSizeChangedListener mSurfaceTextureSizeListener;
+ private TextureView mTextureView;
+ private Matrix mMatrix = null;
+ private float mAspectRatio = 4f / 3f;
+ private final Object mLock = new Object();
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case UPDATE_TRANSFORM_MATRIX:
+ setTransformMatrix(mPreviewWidth, mPreviewHeight);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ public interface SurfaceTextureSizeChangedListener {
+ public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight);
+ }
+
+ private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right,
+ int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ int width = right - left;
+ int height = bottom - top;
+ // Full-screen screennail
+ int w = width;
+ int h = height;
+ if (Util.getDisplayRotation(mActivity) % 180 != 0) {
+ w = height;
+ h = width;
+ }
+ if (mPreviewWidth != width || mPreviewHeight != height) {
+ mPreviewWidth = width;
+ mPreviewHeight = height;
+ onScreenSizeChanged(width, height, w, h);
+ mController.onScreenSizeChanged(width, height, w, h);
+ }
+ }
+ };
+
+ private ValueAnimator.AnimatorListener mAnimatorListener =
+ new ValueAnimator.AnimatorListener() {
+
+ @Override
+ public void onAnimationCancel(Animator arg0) {}
+
+ @Override
+ public void onAnimationEnd(Animator arg0) {
+ mFlashOverlay.setAlpha(0f);
+ mFlashOverlay.setVisibility(View.GONE);
+ mFlashAnim.removeListener(this);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator arg0) {}
+
+ @Override
+ public void onAnimationStart(Animator arg0) {}
+ };
+
+ public PhotoUI(CameraActivity activity, PhotoController controller, View parent) {
+ mActivity = activity;
+ mController = controller;
+ mRootView = parent;
+
+ mActivity.getLayoutInflater().inflate(R.layout.photo_module,
+ (ViewGroup) mRootView, true);
+ mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay);
+ mFlashOverlay = mRootView.findViewById(R.id.flash_overlay);
+ // display the view
+ mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content);
+ mTextureView.setSurfaceTextureListener(this);
+ mTextureView.addOnLayoutChangeListener(mLayoutListener);
+ initIndicators();
+
+ mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button);
+ mSwitcher = (CameraSwitcher) mRootView.findViewById(R.id.camera_switcher);
+ mSwitcher.setCurrentIndex(CameraSwitcher.PHOTO_MODULE_INDEX);
+ mSwitcher.setSwitchListener((CameraSwitchListener) mActivity);
+ mMenuButton = mRootView.findViewById(R.id.menu);
+ if (ApiHelper.HAS_FACE_DETECTION) {
+ ViewStub faceViewStub = (ViewStub) mRootView
+ .findViewById(R.id.face_view_stub);
+ if (faceViewStub != null) {
+ faceViewStub.inflate();
+ mFaceView = (FaceView) mRootView.findViewById(R.id.face_view);
+ setSurfaceTextureSizeChangedListener(
+ (SurfaceTextureSizeChangedListener) mFaceView);
+ }
+ }
+ mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls);
+ ((CameraRootView) mRootView).setDisplayChangeListener(this);
+ }
+
+ public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) {
+ setTransformMatrix(width, height);
+ }
+
+ public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) {
+ mSurfaceTextureSizeListener = listener;
+ }
+
+ public void setPreviewSize(Size size) {
+ int width = size.width;
+ int height = size.height;
+ if (width == 0 || height == 0) {
+ Log.w(TAG, "Preview size should not be 0.");
+ return;
+ }
+ if (width > height) {
+ mAspectRatio = (float) width / height;
+ } else {
+ mAspectRatio = (float) height / width;
+ }
+ mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX);
+ }
+
+ private void setTransformMatrix(int width, int height) {
+ mMatrix = mTextureView.getTransform(mMatrix);
+ int orientation = Util.getDisplayRotation(mActivity);
+ float scaleX = 1f, scaleY = 1f;
+ float scaledTextureWidth, scaledTextureHeight;
+ if (width > height) {
+ scaledTextureWidth = Math.max(width,
+ (int) (height * mAspectRatio));
+ scaledTextureHeight = Math.max(height,
+ (int)(width / mAspectRatio));
+ } else {
+ scaledTextureWidth = Math.max(width,
+ (int) (height / mAspectRatio));
+ scaledTextureHeight = Math.max(height,
+ (int) (width * mAspectRatio));
+ }
+
+ if (mSurfaceTextureUncroppedWidth != scaledTextureWidth ||
+ mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
+ mSurfaceTextureUncroppedWidth = scaledTextureWidth;
+ mSurfaceTextureUncroppedHeight = scaledTextureHeight;
+ if (mSurfaceTextureSizeListener != null) {
+ mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
+ (int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight);
+ }
+ }
+ scaleX = scaledTextureWidth / width;
+ scaleY = scaledTextureHeight / height;
+ mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2);
+ mTextureView.setTransform(mMatrix);
+ }
+
+ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+ synchronized (mLock) {
+ mSurfaceTexture = surface;
+ mLock.notifyAll();
+ }
+ }
+
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+ // Ignored, Camera does all the work for us
+ }
+
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+ mSurfaceTexture = null;
+ mController.stopPreview();
+ Log.w(TAG, "surfaceTexture is destroyed");
+ return true;
+ }
+
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ // Invoked every time there's a new Camera preview frame
+ }
+
+ public View getRootView() {
+ return mRootView;
+ }
+
+ private void initIndicators() {
+ mOnScreenIndicators = new OnScreenIndicators(mActivity,
+ mRootView.findViewById(R.id.on_screen_indicators));
+ }
+
+ public void onCameraOpened(PreferenceGroup prefGroup, ComboPreferences prefs,
+ Camera.Parameters params, OnPreferenceChangedListener listener) {
+ if (mPieRenderer == null) {
+ mPieRenderer = new PieRenderer(mActivity);
+ mPieRenderer.setPieListener(this);
+ mRenderOverlay.addRenderer(mPieRenderer);
+ }
+
+ if (mMenu == null) {
+ mMenu = new PhotoMenu(mActivity, this, mPieRenderer);
+ mMenu.setListener(listener);
+ }
+ mMenu.initialize(prefGroup);
+
+ if (mZoomRenderer == null) {
+ mZoomRenderer = new ZoomRenderer(mActivity);
+ mRenderOverlay.addRenderer(mZoomRenderer);
+ }
+
+ if (mGestures == null) {
+ // this will handle gesture disambiguation and dispatching
+ mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer);
+ mRenderOverlay.setGestures(mGestures);
+ }
+ mGestures.setZoomEnabled(params.isZoomSupported());
+ mGestures.setRenderOverlay(mRenderOverlay);
+ mRenderOverlay.requestLayout();
+
+ initializeZoom(params);
+ updateOnScreenIndicators(params, prefGroup, prefs);
+ }
+
+ private void openMenu() {
+ if (mPieRenderer != null) {
+ // If autofocus is not finished, cancel autofocus so that the
+ // subsequent touch can be handled by PreviewGestures
+ if (mController.getCameraState() == PhotoController.FOCUSING) {
+ mController.cancelAutoFocus();
+ }
+ mPieRenderer.showInCenter();
+ }
+ }
+
+ public void initializeControlByIntent() {
+ mBlocker = mRootView.findViewById(R.id.blocker);
+ mPreviewThumb = mRootView.findViewById(R.id.preview_thumb);
+ mPreviewThumb.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // TODO: go to filmstrip
+ // mActivity.gotoGallery();
+ }
+ });
+ mMenuButton = mRootView.findViewById(R.id.menu);
+ mMenuButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ openMenu();
+ }
+ });
+ if (mController.isImageCaptureIntent()) {
+ hideSwitcher();
+ ViewGroup cameraControls = (ViewGroup) mRootView.findViewById(R.id.camera_controls);
+ mActivity.getLayoutInflater().inflate(R.layout.review_module_control, cameraControls);
+
+ mReviewDoneButton = mRootView.findViewById(R.id.btn_done);
+ mReviewCancelButton = mRootView.findViewById(R.id.btn_cancel);
+ mReviewRetakeButton = mRootView.findViewById(R.id.btn_retake);
+ mReviewCancelButton.setVisibility(View.VISIBLE);
+
+ mReviewDoneButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mController.onCaptureDone();
+ }
+ });
+ mReviewCancelButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mController.onCaptureCancelled();
+ }
+ });
+
+ mReviewRetakeButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mController.onCaptureRetake();
+ }
+ });
+ }
+ }
+
+ public void hideUI() {
+ mCameraControls.setVisibility(View.INVISIBLE);
+ mSwitcher.closePopup();
+ }
+
+ public void showUI() {
+ mCameraControls.setVisibility(View.VISIBLE);
+ }
+
+ public void hideSwitcher() {
+ mSwitcher.closePopup();
+ mSwitcher.setVisibility(View.INVISIBLE);
+ }
+
+ public void showSwitcher() {
+ mSwitcher.setVisibility(View.VISIBLE);
+ }
+ // called from onResume but only the first time
+ public void initializeFirstTime() {
+ // Initialize shutter button.
+ mShutterButton.setImageResource(R.drawable.btn_new_shutter);
+ mShutterButton.setOnShutterButtonListener(mController);
+ mShutterButton.setVisibility(View.VISIBLE);
+ }
+
+ // called from onResume every other time
+ public void initializeSecondTime(Camera.Parameters params) {
+ initializeZoom(params);
+ if (mController.isImageCaptureIntent()) {
+ hidePostCaptureAlert();
+ }
+ if (mMenu != null) {
+ mMenu.reloadPreferences();
+ }
+ }
+
+ public void showLocationDialog() {
+ mLocationDialog = new AlertDialog.Builder(mActivity)
+ .setTitle(R.string.remember_location_title)
+ .setMessage(R.string.remember_location_prompt)
+ .setPositiveButton(R.string.remember_location_yes,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int arg1) {
+ mController.enableRecordingLocation(true);
+ mLocationDialog = null;
+ }
+ })
+ .setNegativeButton(R.string.remember_location_no,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int arg1) {
+ dialog.cancel();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mController.enableRecordingLocation(false);
+ mLocationDialog = null;
+ }
+ })
+ .show();
+ }
+
+ public void initializeZoom(Camera.Parameters params) {
+ if ((params == null) || !params.isZoomSupported()
+ || (mZoomRenderer == null)) return;
+ mZoomMax = params.getMaxZoom();
+ mZoomRatios = params.getZoomRatios();
+ // Currently we use immediate zoom for fast zooming to get better UX and
+ // there is no plan to take advantage of the smooth zoom.
+ if (mZoomRenderer != null) {
+ mZoomRenderer.setZoomMax(mZoomMax);
+ mZoomRenderer.setZoom(params.getZoom());
+ mZoomRenderer.setZoomValue(mZoomRatios.get(params.getZoom()));
+ mZoomRenderer.setOnZoomChangeListener(new ZoomChangeListener());
+ }
+ }
+
+ public void showGpsOnScreenIndicator(boolean hasSignal) { }
+
+ public void hideGpsOnScreenIndicator() { }
+
+ public void overrideSettings(final String ... keyvalues) {
+ mMenu.overrideSettings(keyvalues);
+ }
+
+ public void updateOnScreenIndicators(Camera.Parameters params,
+ PreferenceGroup group, ComboPreferences prefs) {
+ if (params == null) return;
+ mOnScreenIndicators.updateSceneOnScreenIndicator(params.getSceneMode());
+ mOnScreenIndicators.updateExposureOnScreenIndicator(params,
+ CameraSettings.readExposure(prefs));
+ mOnScreenIndicators.updateFlashOnScreenIndicator(params.getFlashMode());
+ int wbIndex = 2;
+ ListPreference pref = group.findPreference(CameraSettings.KEY_WHITE_BALANCE);
+ if (pref != null) {
+ wbIndex = pref.getCurrentIndex();
+ }
+ mOnScreenIndicators.updateWBIndicator(wbIndex);
+ boolean location = RecordLocationPreference.get(
+ prefs, mActivity.getContentResolver());
+ mOnScreenIndicators.updateLocationIndicator(location);
+ }
+
+ public void setCameraState(int state) {
+ }
+
+ public void animateFlash() {
+ // End the previous animation if the previous one is still running
+ if (mFlashAnim != null && mFlashAnim.isRunning()) {
+ mFlashAnim.end();
+ }
+ // Start new flash animation.
+ mFlashOverlay.setVisibility(View.VISIBLE);
+ mFlashAnim = ObjectAnimator.ofFloat((Object) mFlashOverlay, "alpha", 0.3f, 0f);
+ mFlashAnim.setDuration(300);
+ mFlashAnim.addListener(mAnimatorListener);
+ mFlashAnim.start();
+ }
+
+ public void enableGestures(boolean enable) {
+ if (mGestures != null) {
+ mGestures.setEnabled(enable);
+ }
+ }
+
+ // forward from preview gestures to controller
+ @Override
+ public void onSingleTapUp(View view, int x, int y) {
+ mController.onSingleTapUp(view, x, y);
+ }
+
+ public boolean onBackPressed() {
+ if (mPieRenderer != null && mPieRenderer.showsItems()) {
+ mPieRenderer.hide();
+ return true;
+ }
+ // In image capture mode, back button should:
+ // 1) if there is any popup, dismiss them, 2) otherwise, get out of
+ // image capture
+ if (mController.isImageCaptureIntent()) {
+ if (!removeTopLevelPopup()) {
+ // no popup to dismiss, cancel image capture
+ mController.onCaptureCancelled();
+ }
+ return true;
+ } else if (!mController.isCameraIdle()) {
+ // ignore backs while we're taking a picture
+ return true;
+ } else {
+ return removeTopLevelPopup();
+ }
+ }
+
+ public void onSwitchMode(boolean toCamera) {
+ if (toCamera) {
+ showUI();
+ } else {
+ hideUI();
+ }
+ if (mFaceView != null) {
+ mFaceView.setBlockDraw(!toCamera);
+ }
+ if (mPopup != null) {
+ dismissPopup(toCamera);
+ }
+ if (mGestures != null) {
+ mGestures.setEnabled(toCamera);
+ }
+ if (mRenderOverlay != null) {
+ // this can not happen in capture mode
+ mRenderOverlay.setVisibility(toCamera ? View.VISIBLE : View.GONE);
+ }
+ if (mPieRenderer != null) {
+ mPieRenderer.setBlockFocus(!toCamera);
+ }
+ setShowMenu(toCamera);
+ if (!toCamera && mCountDownView != null) mCountDownView.cancelCountDown();
+ }
+
+ public void enablePreviewThumb(boolean enabled) {
+ if (enabled) {
+ mPreviewThumb.setVisibility(View.VISIBLE);
+ } else {
+ mPreviewThumb.setVisibility(View.GONE);
+ }
+ }
+
+ public boolean removeTopLevelPopup() {
+ // Remove the top level popup or dialog box and return true if there's any
+ if (mPopup != null) {
+ dismissPopup();
+ return true;
+ }
+ return false;
+ }
+
+ public void showPopup(AbstractSettingPopup popup) {
+ hideUI();
+ mBlocker.setVisibility(View.INVISIBLE);
+ setShowMenu(false);
+ mPopup = popup;
+ mPopup.setVisibility(View.VISIBLE);
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+ lp.gravity = Gravity.CENTER;
+ ((FrameLayout) mRootView).addView(mPopup, lp);
+ }
+
+ public void dismissPopup() {
+ dismissPopup(true);
+ }
+
+ private void dismissPopup(boolean fullScreen) {
+ if (fullScreen) {
+ showUI();
+ mBlocker.setVisibility(View.VISIBLE);
+ }
+ setShowMenu(fullScreen);
+ if (mPopup != null) {
+ ((FrameLayout) mRootView).removeView(mPopup);
+ mPopup = null;
+ }
+ mMenu.popupDismissed();
+ }
+
+ public void onShowSwitcherPopup() {
+ if (mPieRenderer != null && mPieRenderer.showsItems()) {
+ mPieRenderer.hide();
+ }
+ }
+
+ private void setShowMenu(boolean show) {
+ if (mOnScreenIndicators != null) {
+ mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ if (mMenuButton != null) {
+ mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ public boolean collapseCameraControls() {
+ // Remove all the popups/dialog boxes
+ boolean ret = false;
+ if (mPopup != null) {
+ dismissPopup();
+ ret = true;
+ }
+ onShowSwitcherPopup();
+ return ret;
+ }
+
+ protected void showPostCaptureAlert() {
+ mOnScreenIndicators.setVisibility(View.GONE);
+ mMenuButton.setVisibility(View.GONE);
+ Util.fadeIn(mReviewDoneButton);
+ mShutterButton.setVisibility(View.INVISIBLE);
+ Util.fadeIn(mReviewRetakeButton);
+ pauseFaceDetection();
+ }
+
+ protected void hidePostCaptureAlert() {
+ mOnScreenIndicators.setVisibility(View.VISIBLE);
+ mMenuButton.setVisibility(View.VISIBLE);
+ Util.fadeOut(mReviewDoneButton);
+ mShutterButton.setVisibility(View.VISIBLE);
+ Util.fadeOut(mReviewRetakeButton);
+ resumeFaceDetection();
+ }
+
+ public void setDisplayOrientation(int orientation) {
+ if (mFaceView != null) {
+ mFaceView.setDisplayOrientation(orientation);
+ }
+ }
+
+ // shutter button handling
+
+ public boolean isShutterPressed() {
+ return mShutterButton.isPressed();
+ }
+
+ public void enableShutter(boolean enabled) {
+ if (mShutterButton != null) {
+ mShutterButton.setEnabled(enabled);
+ }
+ }
+
+ public void pressShutterButton() {
+ if (mShutterButton.isInTouchMode()) {
+ mShutterButton.requestFocusFromTouch();
+ } else {
+ mShutterButton.requestFocus();
+ }
+ mShutterButton.setPressed(true);
+ }
+
+ private class ZoomChangeListener implements ZoomRenderer.OnZoomChangedListener {
+ @Override
+ public void onZoomValueChanged(int index) {
+ int newZoom = mController.onZoomChanged(index);
+ if (mZoomRenderer != null) {
+ mZoomRenderer.setZoomValue(mZoomRatios.get(newZoom));
+ }
+ }
+
+ @Override
+ public void onZoomStart() {
+ if (mPieRenderer != null) {
+ mPieRenderer.setBlockFocus(true);
+ }
+ }
+
+ @Override
+ public void onZoomEnd() {
+ if (mPieRenderer != null) {
+ mPieRenderer.setBlockFocus(false);
+ }
+ }
+ }
+
+ @Override
+ public void onPieOpened(int centerX, int centerY) {
+ setSwipingEnabled(false);
+ dismissPopup();
+ if (mFaceView != null) {
+ mFaceView.setBlockDraw(true);
+ }
+ }
+
+ @Override
+ public void onPieClosed() {
+ setSwipingEnabled(true);
+ if (mFaceView != null) {
+ mFaceView.setBlockDraw(false);
+ }
+ }
+
+ public void setSwipingEnabled(boolean enable) {
+ mActivity.setSwipingEnabled(enable);
+ }
+
+ public Object getSurfaceTexture() {
+ synchronized (mLock) {
+ if (mSurfaceTexture == null) {
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Unexpected interruption when waiting to get surface texture");
+ }
+ }
+ }
+ return mSurfaceTexture;
+ }
+
+ // Countdown timer
+
+ private void initializeCountDown() {
+ mActivity.getLayoutInflater().inflate(R.layout.count_down_to_capture,
+ (ViewGroup) mRootView, true);
+ mCountDownView = (CountDownView) (mRootView.findViewById(R.id.count_down_to_capture));
+ mCountDownView.setCountDownFinishedListener((OnCountDownFinishedListener) mController);
+ }
+
+ public boolean isCountingDown() {
+ return mCountDownView != null && mCountDownView.isCountingDown();
+ }
+
+ public void cancelCountDown() {
+ if (mCountDownView == null) return;
+ mCountDownView.cancelCountDown();
+ }
+
+ public void startCountDown(int sec, boolean playSound) {
+ if (mCountDownView == null) initializeCountDown();
+ mCountDownView.startCountDown(sec, playSound);
+ }
+
+ public void showPreferencesToast() {
+ if (mNotSelectableToast == null) {
+ String str = mActivity.getResources().getString(R.string.not_selectable_in_scene_mode);
+ mNotSelectableToast = Toast.makeText(mActivity, str, Toast.LENGTH_SHORT);
+ }
+ mNotSelectableToast.show();
+ }
+
+ public void onPause() {
+ cancelCountDown();
+
+ // Clear UI.
+ collapseCameraControls();
+ if (mFaceView != null) mFaceView.clear();
+
+ if (mLocationDialog != null && mLocationDialog.isShowing()) {
+ mLocationDialog.dismiss();
+ }
+ mLocationDialog = null;
+ mPreviewWidth = 0;
+ mPreviewHeight = 0;
+ }
+
+ // focus UI implementation
+
+ private FocusIndicator getFocusIndicator() {
+ return (mFaceView != null && mFaceView.faceExists()) ? mFaceView : mPieRenderer;
+ }
+
+ @Override
+ public boolean hasFaces() {
+ return (mFaceView != null && mFaceView.faceExists());
+ }
+
+ public void clearFaces() {
+ if (mFaceView != null) mFaceView.clear();
+ }
+
+ @Override
+ public void clearFocus() {
+ FocusIndicator indicator = getFocusIndicator();
+ if (indicator != null) indicator.clear();
+ }
+
+ @Override
+ public void setFocusPosition(int x, int y) {
+ mPieRenderer.setFocus(x, y);
+ }
+
+ @Override
+ public void onFocusStarted() {
+ getFocusIndicator().showStart();
+ }
+
+ @Override
+ public void onFocusSucceeded(boolean timeout) {
+ getFocusIndicator().showSuccess(timeout);
+ }
+
+ @Override
+ public void onFocusFailed(boolean timeout) {
+ getFocusIndicator().showFail(timeout);
+ }
+
+ @Override
+ public void pauseFaceDetection() {
+ if (mFaceView != null) mFaceView.pause();
+ }
+
+ @Override
+ public void resumeFaceDetection() {
+ if (mFaceView != null) mFaceView.resume();
+ }
+
+ public void onStartFaceDetection(int orientation, boolean mirror) {
+ mFaceView.clear();
+ mFaceView.setVisibility(View.VISIBLE);
+ mFaceView.setDisplayOrientation(orientation);
+ mFaceView.setMirror(mirror);
+ mFaceView.resume();
+ }
+
+ @Override
+ public void onFaceDetection(Face[] faces, CameraManager.CameraProxy camera) {
+ mFaceView.setFaces(faces);
+ }
+
+ public void onDisplayChanged() {
+ mCameraControls.checkLayoutFlip();
+ mController.updateCameraOrientation();
+ }
+
+}