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();
+ }
}