diff --git a/res/layout/preferences_dialog.xml b/res/layout/preferences_dialog.xml index e30c117..d78f873 100644 --- a/res/layout/preferences_dialog.xml +++ b/res/layout/preferences_dialog.xml @@ -52,4 +52,12 @@ android:layout_marginBottom="16dp" android:text="@string/menu_ab_perf_mode" android:textSize="16sp" /> + + diff --git a/res/values/config.xml b/res/values/config.xml new file mode 100644 index 0000000..76ab686 --- /dev/null +++ b/res/values/config.xml @@ -0,0 +1,19 @@ + + + + false + diff --git a/res/values/strings.xml b/res/values/strings.xml index 34f2fd3..9804398 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,6 +1,6 @@ + + + diff --git a/src/org/lineageos/updater/UpdatesActivity.java b/src/org/lineageos/updater/UpdatesActivity.java index ad001c8..df9a8fd 100644 --- a/src/org/lineageos/updater/UpdatesActivity.java +++ b/src/org/lineageos/updater/UpdatesActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The LineageOS Project + * Copyright (C) 2017-2020 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,10 +27,12 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.IBinder; +import android.os.SystemProperties; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; +import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; @@ -38,6 +40,7 @@ import android.view.animation.RotateAnimation; import android.widget.Spinner; import android.widget.Switch; import android.widget.TextView; +import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; @@ -414,6 +417,7 @@ public class UpdatesActivity extends UpdatesListActivity { Switch autoDelete = view.findViewById(R.id.preferences_auto_delete_updates); Switch dataWarning = view.findViewById(R.id.preferences_mobile_data_warning); Switch abPerfMode = view.findViewById(R.id.preferences_ab_perf_mode); + Switch updateRecovery = view.findViewById(R.id.preferences_update_recovery); if (!Utils.isABDevice()) { abPerfMode.setVisibility(View.GONE); @@ -425,6 +429,33 @@ public class UpdatesActivity extends UpdatesListActivity { dataWarning.setChecked(prefs.getBoolean(Constants.PREF_MOBILE_DATA_WARNING, true)); abPerfMode.setChecked(prefs.getBoolean(Constants.PREF_AB_PERF_MODE, false)); + if (getResources().getBoolean(R.bool.config_hideRecoveryUpdate)) { + // Hide the update feature if explicitely requested. + // Might be the case of A-only devices using prebuilt vendor images. + updateRecovery.setVisibility(View.GONE); + } else if (Utils.isRecoveryUpdateExecPresent()) { + updateRecovery.setChecked(prefs.getBoolean(Constants.PREF_UPDATE_RECOVERY, false)); + } else { + // There is no recovery updater script in the device, so the feature is considered + // forcefully enabled, just to avoid users to be confused and complain that + // recovery gets overwritten. That's the case of A/B and recovery-in-boot devices. + updateRecovery.setChecked(true); + updateRecovery.setOnTouchListener(new View.OnTouchListener() { + private Toast forcedUpdateToast = null; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (forcedUpdateToast != null) { + forcedUpdateToast.cancel(); + } + forcedUpdateToast = Toast.makeText(getApplicationContext(), + getString(R.string.toast_forced_update_recovery), Toast.LENGTH_SHORT); + forcedUpdateToast.show(); + return true; + } + }); + } + new AlertDialog.Builder(this) .setTitle(R.string.menu_preferences) .setView(view) @@ -438,6 +469,8 @@ public class UpdatesActivity extends UpdatesListActivity { dataWarning.isChecked()) .putBoolean(Constants.PREF_AB_PERF_MODE, abPerfMode.isChecked()) + .putBoolean(Constants.PREF_UPDATE_RECOVERY, + updateRecovery.isChecked()) .apply(); if (Utils.isUpdateCheckEnabled(this)) { @@ -451,6 +484,11 @@ public class UpdatesActivity extends UpdatesListActivity { boolean enableABPerfMode = abPerfMode.isChecked(); mUpdaterService.getUpdaterController().setPerformanceMode(enableABPerfMode); } + if (Utils.isRecoveryUpdateExecPresent()) { + boolean enableRecoveryUpdate = updateRecovery.isChecked(); + SystemProperties.set(Constants.UPDATE_RECOVERY_PROPERTY, + String.valueOf(enableRecoveryUpdate)); + } }) .show(); } diff --git a/src/org/lineageos/updater/misc/Constants.java b/src/org/lineageos/updater/misc/Constants.java index 81e7c1a..5e1cc8b 100644 --- a/src/org/lineageos/updater/misc/Constants.java +++ b/src/org/lineageos/updater/misc/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The LineageOS Project + * Copyright (C) 2017-2020 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ public final class Constants { public static final String PREF_AB_PERF_MODE = "ab_perf_mode"; public static final String PREF_MOBILE_DATA_WARNING = "pref_mobile_data_warning"; public static final String PREF_NEEDS_REBOOT_ID = "needs_reboot_id"; + public static final String PREF_UPDATE_RECOVERY = "update_recovery"; public static final String UNCRYPT_FILE_EXT = ".uncrypt"; @@ -52,4 +53,7 @@ public final class Constants { public static final String PREF_INSTALL_PACKAGE_PATH = "install_package_path"; public static final String PREF_INSTALL_AGAIN = "install_again"; public static final String PREF_INSTALL_NOTIFIED = "install_notified"; + + public static final String UPDATE_RECOVERY_EXEC = "/vendor/bin/install-recovery.sh"; + public static final String UPDATE_RECOVERY_PROPERTY = "persist.vendor.recovery_update"; } diff --git a/src/org/lineageos/updater/misc/Utils.java b/src/org/lineageos/updater/misc/Utils.java index caf80c9..28f3c4c 100644 --- a/src/org/lineageos/updater/misc/Utils.java +++ b/src/org/lineageos/updater/misc/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The LineageOS Project + * Copyright (C) 2017-2020 The LineageOS Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -401,4 +401,8 @@ public class Utils { return AlarmManager.INTERVAL_DAY * 30; } } + + public static boolean isRecoveryUpdateExecPresent() { + return new File(Constants.UPDATE_RECOVERY_EXEC).exists(); + } }