blob: 96a8de8d4231f74d5361369764113c2fa6fc7e72 [file] [log] [blame]
/*
* SPDX-FileCopyrightText: 2016 The CyanogenMod Project
* SPDX-FileCopyrightText: 2017-2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.setupwizard;
import static org.lineageos.setupwizard.SetupWizardApp.LOGV;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import org.lineageos.setupwizard.util.SetupWizardUtils;
public class FinishActivity extends BaseSetupWizardActivity {
public static final String TAG = FinishActivity.class.getSimpleName();
private final Handler mHandler = new Handler(Looper.getMainLooper());
// "Why not just start this activity with an Intent extra?" you might ask. Been there.
// We need this to affect the theme, and even onCreate is not early enough for that,
// so "static volatile boolean" it is. Feel free to rework this if you dare.
private static volatile boolean sIsFinishing;
private View mRootView;
private Resources.Theme mEdgeToEdgeWallpaperBackgroundTheme;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, R.anim.translucent_enter,
R.anim.translucent_exit);
if (LOGV) {
logActivityState("onCreate savedInstanceState=" + savedInstanceState);
}
setNextText(R.string.start);
// Edge-to-edge. Needed for the background view to fill the full screen.
final Window window = getWindow();
window.setDecorFitsSystemWindows(false);
// Make sure 3-button navigation bar is the same color as the rest of the screen.
window.setNavigationBarContrastEnforced(false);
// Ensure the main layout (not including the background view) does not get obscured by bars.
mRootView = findViewById(R.id.root);
ViewCompat.setOnApplyWindowInsetsListener(mRootView, (view, windowInsets) -> {
final View linearLayout = findViewById(R.id.linear_layout);
final Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
final MarginLayoutParams params = (MarginLayoutParams) linearLayout.getLayoutParams();
params.leftMargin = insets.left;
params.topMargin = insets.top;
params.rightMargin = insets.right;
params.bottomMargin = insets.bottom;
linearLayout.setLayoutParams(params);
return WindowInsetsCompat.CONSUMED;
});
if (sIsFinishing) {
startFinishSequence();
}
}
private void disableActivityTransitions() {
overrideActivityTransition(OVERRIDE_TRANSITION_OPEN, 0, 0);
overrideActivityTransition(OVERRIDE_TRANSITION_CLOSE, 0, 0);
}
@Override
protected void applyForwardTransition() {
if (!sIsFinishing) {
super.applyForwardTransition();
}
}
@Override
protected void applyBackwardTransition() {
if (!sIsFinishing) {
super.applyBackwardTransition();
}
}
@Override
protected int getLayoutResId() {
return R.layout.finish_activity;
}
@Override
public Resources.Theme getTheme() {
Resources.Theme theme = super.getTheme();
if (sIsFinishing) {
if (mEdgeToEdgeWallpaperBackgroundTheme == null) {
theme.applyStyle(R.style.EdgeToEdgeWallpaperBackground, true);
mEdgeToEdgeWallpaperBackgroundTheme = theme;
}
return mEdgeToEdgeWallpaperBackgroundTheme;
}
return theme;
}
@Override
public void onNavigateNext() {
if (!sIsFinishing) {
sIsFinishing = true;
startActivity(getIntent());
finish();
disableActivityTransitions();
}
hideNextButton();
}
private void startFinishSequence() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
hideNextButton();
// Begin outro animation.
if (mRootView.isAttachedToWindow()) {
mHandler.post(() -> animateOut());
} else {
mRootView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
mHandler.post(() -> animateOut());
}
@Override
public void onViewDetachedFromWindow(View v) {
// Do nothing
}
});
}
}
private void animateOut() {
final int cx = (mRootView.getLeft() + mRootView.getRight()) / 2;
final int cy = (mRootView.getTop() + mRootView.getBottom()) / 2;
final float fullRadius = (float) Math.hypot(cx, cy);
Animator anim =
ViewAnimationUtils.createCircularReveal(mRootView, cx, cy, fullRadius, 0f);
anim.setDuration(900);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mRootView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
mRootView.setVisibility(View.INVISIBLE);
mHandler.post(() -> {
if (LOGV) {
Log.v(TAG, "Animation ended");
}
SetupWizardUtils.finishSetupWizard(FinishActivity.this);
});
}
});
anim.start();
}
}