blob: 20da8773f38728ae3bc2aa9eb3064404d9b45967 [file] [log] [blame]
/*
* 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
}
}