blob: 0427a4d3a080f2262795510e7a28f4ea0360b48c [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 android.os.Binder.getCallingUserHandle;
import static android.os.UserHandle.USER_CURRENT;
import static org.lineageos.setupwizard.Manifest.permission.FINISH_SETUP;
import static org.lineageos.setupwizard.SetupWizardApp.ACTION_FINISHED;
import static org.lineageos.setupwizard.SetupWizardApp.ACTION_SETUP_COMPLETE;
import static org.lineageos.setupwizard.SetupWizardApp.DISABLE_NAV_KEYS;
import static org.lineageos.setupwizard.SetupWizardApp.ENABLE_RECOVERY_UPDATE;
import static org.lineageos.setupwizard.SetupWizardApp.KEY_SEND_METRICS;
import static org.lineageos.setupwizard.SetupWizardApp.LOGV;
import static org.lineageos.setupwizard.SetupWizardApp.NAVIGATION_OPTION_KEY;
import static org.lineageos.setupwizard.SetupWizardApp.UPDATE_RECOVERY_PROP;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.om.IOverlayManager;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Log;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.widget.ImageView;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import lineageos.providers.LineageSettings;
import org.lineageos.setupwizard.util.SetupWizardUtils;
public class FinishActivity extends BaseSetupWizardActivity {
public static final String TAG = FinishActivity.class.getSimpleName();
private ImageView mBackground;
private SetupWizardApp mSetupWizardApp;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private boolean mIsFinishing;
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (LOGV) {
Log.v(TAG, "onReceive intent=" + intent);
}
if (intent != null && intent.getAction().equals(ACTION_FINISHED)) {
unregisterReceiver(mIntentReceiver);
completeSetup();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.translucent_enter, R.anim.translucent_exit);
if (LOGV) {
logActivityState("onCreate savedInstanceState=" + savedInstanceState);
}
mSetupWizardApp = (SetupWizardApp) getApplication();
mBackground = findViewById(R.id.background);
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.
final View rootView = findViewById(R.id.root);
ViewCompat.setOnApplyWindowInsetsListener(rootView, (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;
});
}
@Override
protected int getLayoutResId() {
return R.layout.finish_activity;
}
@Override
public void onNavigateNext() {
startFinishSequence();
}
private void startFinishSequence() {
if (mIsFinishing) {
return;
}
mIsFinishing = true;
// Listen for completion from the exit service.
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_FINISHED);
registerReceiver(mIntentReceiver, filter, null, null);
Intent i = new Intent(ACTION_SETUP_COMPLETE);
i.setPackage(getPackageName());
sendBroadcastAsUser(i, getCallingUserHandle(), FINISH_SETUP);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
hideNextButton();
// Begin outro animation.
animateOut();
}
private void animateOut() {
final View rootView = findViewById(R.id.root);
final int cx = (rootView.getLeft() + rootView.getRight()) / 2;
final int cy = (rootView.getTop() + rootView.getBottom()) / 2;
final float fullRadius = (float) Math.hypot(cx, cy);
Animator anim =
ViewAnimationUtils.createCircularReveal(rootView, cx, cy, fullRadius, 0f);
anim.setDuration(900);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
rootView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
rootView.setVisibility(View.INVISIBLE);
mHandler.post(() -> {
if (LOGV) {
Log.v(TAG, "Animation ended");
}
// Start exit procedures, including the exit service.
SetupWizardUtils.startSetupWizardExitProcedure(FinishActivity.this);
});
}
});
anim.start();
}
private void completeSetup() {
handleEnableMetrics(mSetupWizardApp);
handleNavKeys(mSetupWizardApp);
handleRecoveryUpdate(mSetupWizardApp);
handleNavigationOption(mSetupWizardApp);
final WallpaperManager wallpaperManager =
WallpaperManager.getInstance(mSetupWizardApp);
wallpaperManager.forgetLoadedWallpaper();
finishAffinity();
nextAction(RESULT_OK);
SetupWizardUtils.enableStatusBar();
Log.i(TAG, "Setup complete!");
}
private static void handleEnableMetrics(SetupWizardApp setupWizardApp) {
Bundle privacyData = setupWizardApp.getSettingsBundle();
if (privacyData != null
&& privacyData.containsKey(KEY_SEND_METRICS)) {
LineageSettings.Secure.putInt(setupWizardApp.getContentResolver(),
LineageSettings.Secure.STATS_COLLECTION,
privacyData.getBoolean(KEY_SEND_METRICS)
? 1 : 0);
}
}
private static void handleNavKeys(SetupWizardApp setupWizardApp) {
if (setupWizardApp.getSettingsBundle().containsKey(DISABLE_NAV_KEYS)) {
writeDisableNavkeysOption(setupWizardApp,
setupWizardApp.getSettingsBundle().getBoolean(DISABLE_NAV_KEYS));
}
}
private static void handleRecoveryUpdate(SetupWizardApp setupWizardApp) {
if (setupWizardApp.getSettingsBundle().containsKey(ENABLE_RECOVERY_UPDATE)) {
boolean update = setupWizardApp.getSettingsBundle()
.getBoolean(ENABLE_RECOVERY_UPDATE);
SystemProperties.set(UPDATE_RECOVERY_PROP, String.valueOf(update));
}
}
private void handleNavigationOption(Context context) {
Bundle settingsBundle = mSetupWizardApp.getSettingsBundle();
if (settingsBundle.containsKey(NAVIGATION_OPTION_KEY)) {
IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
ServiceManager.getService(Context.OVERLAY_SERVICE));
String selectedNavMode = settingsBundle.getString(NAVIGATION_OPTION_KEY);
try {
overlayManager.setEnabledExclusiveInCategory(selectedNavMode, USER_CURRENT);
} catch (Exception ignored) {
}
}
}
private static void writeDisableNavkeysOption(Context context, boolean enabled) {
final boolean virtualKeysEnabled = LineageSettings.System.getIntForUser(
context.getContentResolver(), LineageSettings.System.FORCE_SHOW_NAVBAR, 0,
UserHandle.USER_CURRENT) != 0;
if (enabled != virtualKeysEnabled) {
LineageSettings.System.putIntForUser(context.getContentResolver(),
LineageSettings.System.FORCE_SHOW_NAVBAR, enabled ? 1 : 0,
UserHandle.USER_CURRENT);
}
}
}