| /* |
| * Copyright (C) 2020 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.wm.shell.startingsurface; |
| |
| import static android.view.View.GONE; |
| |
| import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLASHSCREEN_EXIT_ANIM; |
| |
| import android.animation.Animator; |
| import android.content.Context; |
| import android.graphics.Rect; |
| import android.util.Slog; |
| import android.view.SurfaceControl; |
| import android.view.View; |
| import android.window.SplashScreenView; |
| |
| import com.android.internal.jank.InteractionJankMonitor; |
| import com.android.wm.shell.R; |
| import com.android.wm.shell.common.TransactionPool; |
| |
| /** |
| * Default animation for exiting the splash screen window. |
| * @hide |
| */ |
| public class SplashScreenExitAnimation implements Animator.AnimatorListener { |
| private static final boolean DEBUG_EXIT_ANIMATION = false; |
| private static final String TAG = StartingWindowController.TAG; |
| |
| private final SurfaceControl mFirstWindowSurface; |
| private final Rect mFirstWindowFrame = new Rect(); |
| private final SplashScreenView mSplashScreenView; |
| private final int mMainWindowShiftLength; |
| private final int mIconFadeOutDuration; |
| private final int mAppRevealDelay; |
| private final int mAppRevealDuration; |
| private final int mAnimationDuration; |
| private final float mIconStartAlpha; |
| private final float mBrandingStartAlpha; |
| private final TransactionPool mTransactionPool; |
| // TODO(b/261167708): Clean enter animation code after moving Letterbox code to Shell |
| private final float mRoundedCornerRadius; |
| |
| private Runnable mFinishCallback; |
| |
| SplashScreenExitAnimation(Context context, SplashScreenView view, SurfaceControl leash, |
| Rect frame, int mainWindowShiftLength, TransactionPool pool, Runnable handleFinish, |
| float roundedCornerRadius) { |
| mSplashScreenView = view; |
| mFirstWindowSurface = leash; |
| mRoundedCornerRadius = roundedCornerRadius; |
| if (frame != null) { |
| mFirstWindowFrame.set(frame); |
| } |
| |
| View iconView = view.getIconView(); |
| |
| // If the icon and the background are invisible, don't animate it |
| if (iconView == null || iconView.getLayoutParams().width == 0 |
| || iconView.getLayoutParams().height == 0) { |
| mIconFadeOutDuration = 0; |
| mIconStartAlpha = 0; |
| mBrandingStartAlpha = 0; |
| mAppRevealDelay = 0; |
| } else { |
| iconView.setLayerType(View.LAYER_TYPE_HARDWARE, null); |
| // The branding view could only exists when the icon is present. |
| final View brandingView = view.getBrandingView(); |
| if (brandingView != null) { |
| mBrandingStartAlpha = brandingView.getAlpha(); |
| } else { |
| mBrandingStartAlpha = 0; |
| } |
| mIconFadeOutDuration = context.getResources().getInteger( |
| R.integer.starting_window_app_reveal_icon_fade_out_duration); |
| mAppRevealDelay = context.getResources().getInteger( |
| R.integer.starting_window_app_reveal_anim_delay); |
| mIconStartAlpha = iconView.getAlpha(); |
| } |
| mAppRevealDuration = context.getResources().getInteger( |
| R.integer.starting_window_app_reveal_anim_duration); |
| mAnimationDuration = Math.max(mIconFadeOutDuration, mAppRevealDelay + mAppRevealDuration); |
| mMainWindowShiftLength = mainWindowShiftLength; |
| mFinishCallback = handleFinish; |
| mTransactionPool = pool; |
| } |
| |
| void startAnimations() { |
| SplashScreenExitAnimationUtils.startAnimations(mSplashScreenView, mFirstWindowSurface, |
| mMainWindowShiftLength, mTransactionPool, mFirstWindowFrame, mAnimationDuration, |
| mIconFadeOutDuration, mIconStartAlpha, mBrandingStartAlpha, mAppRevealDelay, |
| mAppRevealDuration, this, mRoundedCornerRadius); |
| } |
| |
| private void reset() { |
| if (DEBUG_EXIT_ANIMATION) { |
| Slog.v(TAG, "vanish animation finished"); |
| } |
| |
| if (mSplashScreenView.isAttachedToWindow()) { |
| mSplashScreenView.setVisibility(GONE); |
| if (mFinishCallback != null) { |
| mFinishCallback.run(); |
| mFinishCallback = null; |
| } |
| } |
| } |
| |
| @Override |
| public void onAnimationStart(Animator animation) { |
| InteractionJankMonitor.getInstance().begin(mSplashScreenView, CUJ_SPLASHSCREEN_EXIT_ANIM); |
| } |
| |
| @Override |
| public void onAnimationEnd(Animator animation) { |
| reset(); |
| InteractionJankMonitor.getInstance().end(CUJ_SPLASHSCREEN_EXIT_ANIM); |
| } |
| |
| @Override |
| public void onAnimationCancel(Animator animation) { |
| reset(); |
| InteractionJankMonitor.getInstance().cancel(CUJ_SPLASHSCREEN_EXIT_ANIM); |
| } |
| |
| @Override |
| public void onAnimationRepeat(Animator animation) { |
| // ignore |
| } |
| } |