Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e20e233 authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Implement capture animation" into gb-ub-photos-carlsbad

parents 3d11536f ae7ef761
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -59,11 +59,12 @@
            android:scaleType="center"
            android:src="@drawable/btn_new_shutter" />

        <View
        <ImageView
            android:id="@+id/preview_thumb"
            android:visibility="invisible"
            android:layout_width="@dimen/capture_size"
            android:layout_height="@dimen/capture_size"
            android:scaleType="centerInside"
            android:layout_gravity="top|right" />

</com.android.camera.ui.CameraControls>
+2 −1
Original line number Diff line number Diff line
@@ -59,11 +59,12 @@
            android:scaleType="center"
            android:src="@drawable/btn_new_shutter" />

        <View
        <ImageView
            android:id="@+id/preview_thumb"
            android:visibility="invisible"
            android:layout_width="@dimen/capture_size"
            android:layout_height="@dimen/capture_size"
            android:scaleType="centerInside"
            android:layout_gravity="top|right" />

</com.android.camera.ui.CameraControls>
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
@@ -21,6 +21,13 @@
        android:id="@+id/preview_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <View
        android:id="@+id/flash_overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:visibility="gone"
        android:alpha="0" />
    <FrameLayout android:id="@+id/preview_border"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
+157 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 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.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;

/**
 * Class to handle animations.
 */

public class AnimationManager {

    public static final float FLASH_ALPHA_START = 0.3f;
    public static final float FLASH_ALPHA_END = 0f;
    public static final int FLASH_DURATION = 300;

    public static final int SHRINK_DURATION = 400;
    public static final int HOLD_DURATION = 2500;
    public static final int SLIDE_DURATION = 1100;

    private ObjectAnimator mFlashAnim;
    private AnimatorSet mCaptureAnimator;

    /**
     * Starts capture animation.
     * @param view a thumbnail view that shows a picture captured and gets animated
     */
    public void startCaptureAnimation(final View view) {
        if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) {
            mCaptureAnimator.cancel();
        }
        View parentView = (View) view.getParent();
        float slideDistance = (float) (parentView.getWidth() - view.getLeft());

        float scaleX = ((float) parentView.getWidth()) / ((float) view.getWidth());
        float scaleY = ((float) parentView.getHeight()) / ((float) view.getHeight());
        float scale = scaleX > scaleY ? scaleX : scaleY;

        int centerX = view.getLeft() + view.getWidth() / 2;
        int centerY = view.getTop() + view.getHeight() / 2;

        ObjectAnimator slide = ObjectAnimator.ofFloat(view, "translationX", 0f, slideDistance)
                .setDuration(AnimationManager.SLIDE_DURATION);
        slide.setStartDelay(AnimationManager.SHRINK_DURATION + AnimationManager.HOLD_DURATION);
        mCaptureAnimator = new AnimatorSet();
        mCaptureAnimator.playTogether(
                ObjectAnimator.ofFloat(view, "scaleX", scale, 1f)
                        .setDuration(AnimationManager.SHRINK_DURATION),
                ObjectAnimator.ofFloat(view, "scaleY", scale, 1f)
                        .setDuration(AnimationManager.SHRINK_DURATION),
                ObjectAnimator.ofFloat(view, "translationX",
                        parentView.getWidth() / 2 - centerX, 0f)
                        .setDuration(AnimationManager.SHRINK_DURATION),
                ObjectAnimator.ofFloat(view, "translationY",
                        parentView.getHeight() / 2 - centerY, 0f)
                        .setDuration(AnimationManager.SHRINK_DURATION),
                slide);
        mCaptureAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
                view.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                view.setScaleX(1f);
                view.setScaleX(1f);
                view.setTranslationX(0f);
                view.setTranslationY(0f);
                view.setVisibility(View.INVISIBLE);
                mCaptureAnimator.removeAllListeners();
                mCaptureAnimator = null;
            }

            @Override
            public void onAnimationCancel(Animator animator) {
                view.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationRepeat(Animator animator) {
                // Do nothing.
            }
        });
        mCaptureAnimator.start();
    }

   /**
    * Starts flash animation.
    * @params flashOverlay the overlay that will animate on alpha to make the flash impression
    */
    public void startFlashAnimation(final View flashOverlay) {
        // End the previous animation if the previous one is still running
        if (mFlashAnim != null && mFlashAnim.isRunning()) {
            mFlashAnim.cancel();
        }
        // Start new flash animation.
        mFlashAnim = ObjectAnimator.ofFloat(flashOverlay, "alpha",
                AnimationManager.FLASH_ALPHA_START, AnimationManager.FLASH_ALPHA_END);
        mFlashAnim.setDuration(AnimationManager.FLASH_DURATION);
        mFlashAnim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
                flashOverlay.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                flashOverlay.setAlpha(0f);
                flashOverlay.setVisibility(View.GONE);
                mFlashAnim.removeAllListeners();
                mFlashAnim = null;
            }

            @Override
            public void onAnimationCancel(Animator animator) {
                // Do nothing.
            }

            @Override
            public void onAnimationRepeat(Animator animator) {
                // Do nothing.
            }
        });
        mFlashAnim.start();
    }

    /**
     * Cancels on-going flash animation and capture animation, if any.
     */
    public void cancelAnimations() {
        // End the previous animation if the previous one is still running
        if (mFlashAnim != null && mFlashAnim.isRunning()) {
            mFlashAnim.cancel();
        }
        if (mCaptureAnimator != null && mCaptureAnimator.isStarted()) {
            mCaptureAnimator.cancel();
        }
    }
}
 No newline at end of file
+15 −36
Original line number Diff line number Diff line
@@ -104,7 +104,6 @@ public class PhotoModule
    private static final int START_PREVIEW_DONE = 10;
    private static final int OPEN_CAMERA_FAIL = 11;
    private static final int CAMERA_DISABLED = 12;
    private static final int CAPTURE_ANIMATION_DONE = 13;

    // The subset of parameters we need to update in setCameraParameters().
    private static final int UPDATE_PARAM_INITIALIZE = 1;
@@ -171,13 +170,6 @@ public class PhotoModule
        }
    };

    private Runnable mFlashRunnable = new Runnable() {
        @Override
        public void run() {
            animateFlash();
        }
    };

    private final StringBuilder mBuilder = new StringBuilder();
    private final Formatter mFormatter = new Formatter(mBuilder);
    private final Object[] mFormatterArgs = new Object[1];
@@ -395,10 +387,6 @@ public class PhotoModule
                            R.string.camera_disabled);
                    break;
                }
                case CAPTURE_ANIMATION_DONE: {
                    mUI.enablePreviewThumb(false);
                    break;
                }
            }
        }
    }
@@ -685,10 +673,10 @@ public class PhotoModule
    private final class ShutterCallback
            implements CameraShutterCallback {

        private boolean mAnimateFlash;
        private boolean mNeedsAnimation;

        public ShutterCallback(boolean animateFlash) {
            mAnimateFlash = animateFlash;
        public ShutterCallback(boolean needsAnimation) {
            mNeedsAnimation = needsAnimation;
        }

        @Override
@@ -696,8 +684,13 @@ public class PhotoModule
            mShutterCallbackTime = System.currentTimeMillis();
            mShutterLag = mShutterCallbackTime - mCaptureStartTime;
            Log.v(TAG, "mShutterLag = " + mShutterLag + "ms");
            if (mAnimateFlash) {
                mActivity.runOnUiThread(mFlashRunnable);
            if (mNeedsAnimation) {
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        animateAfterShutter();
                    }
                });
            }
        }
    }
@@ -736,9 +729,11 @@ public class PhotoModule
            if (mPaused) {
                return;
            }
            //TODO: We should show the picture taken rather than frozen preview here
            if (mIsImageCaptureIntent) {
                stopPreview();
            } else {
                // Animate capture with real jpeg data instead of a preview frame.
                mUI.animateCapture(jpegData);
            }
            if (mSceneMode == Util.SCENE_MODE_HDR) {
                mUI.showSwitcher();
@@ -763,18 +758,6 @@ public class PhotoModule
            Log.v(TAG, "mPictureDisplayedToJpegCallbackTime = "
                    + mPictureDisplayedToJpegCallbackTime + "ms");

             /*TODO:
            // Only animate when in full screen capture mode
            // i.e. If monkey/a user swipes to the gallery during picture taking,
            // don't show animation
            if (ApiHelper.HAS_SURFACE_TEXTURE && !mIsImageCaptureIntent
                    && mActivity.mShowCameraAppView) {
                // Finish capture animation
                mHandler.removeMessages(CAPTURE_ANIMATION_DONE);
                ((CameraScreenNail) mActivity.mCameraScreenNail).animateSlide();
                mHandler.sendEmptyMessageDelayed(CAPTURE_ANIMATION_DONE,
                        CaptureAnimManager.getAnimationDuration());
            } */
            mFocusManager.updateFocusUI(); // Ensure focus indicator is hidden.
            if (!mIsImageCaptureIntent) {
                if (ApiHelper.CAN_START_PREVIEW_IN_JPEG_CALLBACK) {
@@ -920,16 +903,12 @@ public class PhotoModule
        }
    }

    private void animateFlash() {
    private void animateAfterShutter() {
        // Only animate when in full screen capture mode
        // i.e. If monkey/a user swipes to the gallery during picture taking,
        // don't show animation
        if (!mIsImageCaptureIntent) {
            mUI.animateFlash();

            // TODO: mUI.enablePreviewThumb(true);
            // mHandler.sendEmptyMessageDelayed(CAPTURE_ANIMATION_DONE,
            //        CaptureAnimManager.getAnimationDuration());
        }
    }

@@ -949,7 +928,7 @@ public class PhotoModule
        final boolean animateBefore = (mSceneMode == Util.SCENE_MODE_HDR);

        if (animateBefore) {
            animateFlash();
            animateAfterShutter();
        }

        // Set rotation and gps data.
Loading