diff --git a/res/values/strings.xml b/res/values/strings.xml
index fc92d52486081e9a374573e6a0b22fa67257137b..d6b241cc293dec3b79004ce15e0b994982c68699 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -41,7 +41,7 @@
Downloading
Download paused
Download error
- Download completed
+ Update is ready to be installed
Starting download
Update failed
Installation suspended
@@ -53,6 +53,7 @@
Pause
Resume
Suspend
+ Reboot and install
Installing update package
Install error
@@ -108,6 +109,7 @@
You are running the latest /e/OS version. To manually check for updates, use the Refresh button.
Download
+ Apply update
Pause
Resume
Install
diff --git a/src/org/lineageos/updater/UpdatesListAdapter.java b/src/org/lineageos/updater/UpdatesListAdapter.java
index 7ee4b3dc2d2f6ec808afdbfdfedd1d969e230827..ab025ffbd4a25786ee25e89ebc7c072d52d51014 100644
--- a/src/org/lineageos/updater/UpdatesListAdapter.java
+++ b/src/org/lineageos/updater/UpdatesListAdapter.java
@@ -18,11 +18,9 @@ package org.lineageos.updater;
import android.app.Activity;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
-import android.os.BatteryManager;
import android.os.Build;
import android.os.PowerManager;
import android.text.SpannableString;
@@ -74,10 +72,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter mDownloadIds;
@@ -256,7 +250,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter {
if (checkbox.isChecked()) {
preferences.edit()
@@ -383,7 +379,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter {
AlertDialog.Builder freeSpaceDialog = getSpaceDialog(
@@ -507,7 +504,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter= required;
- }
}
diff --git a/src/org/lineageos/updater/controller/UpdaterService.java b/src/org/lineageos/updater/controller/UpdaterService.java
index f5ee697b846b689807c18b7443e5a26f606f3da6..ba4baafdadd0529fdf43635fd657d9ecc9f182a1 100644
--- a/src/org/lineageos/updater/controller/UpdaterService.java
+++ b/src/org/lineageos/updater/controller/UpdaterService.java
@@ -28,6 +28,7 @@ import android.content.SharedPreferences;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
+import android.service.notification.StatusBarNotification;
import android.text.format.Formatter;
import android.util.Log;
@@ -245,12 +246,27 @@ public class UpdaterService extends Service {
private void tryStopSelf() {
if (!mHasClients && !mUpdaterController.hasActiveDownloads() &&
- !mUpdaterController.isInstallingUpdate()) {
+ !mUpdaterController.isInstallingUpdate() && !areNotificationsActive()) {
Log.d(TAG, "Service no longer needed, stopping");
stopSelf();
}
}
+ private boolean areNotificationsActive() {
+ NotificationManager notificationManager =
+ (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ StatusBarNotification[] notifications = notificationManager.getActiveNotifications();
+ if (notifications != null && notifications.length > 0) {
+ for (StatusBarNotification notification : notifications) {
+ if (notification.getId() == NOTIFICATION_ID &&
+ notification.getPackageName().equals(getPackageName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private void handleUpdateStatusChange(UpdateInfo update) {
switch (update.getStatus()) {
case DELETED: {
@@ -346,12 +362,45 @@ public class UpdaterService extends Service {
mNotificationBuilder.setSmallIcon(R.drawable.ic_system_update);
mNotificationBuilder.setProgress(0, 0, false);
String text = getString(R.string.download_completed_notification);
+ boolean hasRequiredSpace = Utils.availableFreeSpace() > (update.getFileSize() * 2);
+
+ if (!Utils.canInstall(update) || !Utils.isBatteryLevelOk(this)
+ || !hasRequiredSpace) {
+ /* Show notification if any of the below condition didn't met. */
+ text = getString(R.string.blocked_update_dialog_title) + ". ";
+ if (!Utils.isBatteryLevelOk(this)) {
+ text = text + getString(R.string.dialog_battery_low_title);
+ } else if (!hasRequiredSpace) {
+ text = text + getString(R.string.dialog_free_space_low_title);
+ } else if (!Utils.canInstall(update)) {
+ text = text + getString(R.string.verification_failed_notification);
+ }
+ } else if (!Utils.isABDevice()) {
+ /* Add action to reboot and install for Non-A/B devices. */
+ mNotificationBuilder.mActions.clear();
+ mNotificationBuilder.addAction(R.drawable.ic_system_update,
+ getString(R.string.reboot_install),
+ getInstallationPendingIntent(update.getDownloadId()));
+ }
+
mNotificationBuilder.setContentText(text);
mNotificationBuilder.setTicker(text);
mNotificationBuilder.setOngoing(false);
mNotificationBuilder.setAutoCancel(true);
mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build());
- tryStopSelf();
+
+ /* Make sure these conditions are met before auto install
+ - Can install package (Is a newer build or downgrade allowed)
+ - Battery level (Above 30% if discharging or 20% if charging)
+ - Free space to install (Double the size of the ota zip)
+ */
+ if (Utils.isABDevice() && Utils.canInstall(update)
+ && Utils.isBatteryLevelOk(this) && hasRequiredSpace) {
+ Utils.triggerUpdate(this, update.getDownloadId());
+ } else {
+ tryStopSelf();
+ }
+
break;
}
case VERIFICATION_FAILED: {
@@ -528,6 +577,14 @@ public class UpdaterService extends Service {
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
+ private PendingIntent getInstallationPendingIntent(String downloadId) {
+ final Intent intent = new Intent(this, UpdaterService.class);
+ intent.setAction(ACTION_INSTALL_UPDATE);
+ intent.putExtra(UpdaterService.EXTRA_DOWNLOAD_ID, downloadId);
+ return PendingIntent.getService(this, 0, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
+ }
+
private PendingIntent getResumeInstallationPendingIntent() {
final Intent intent = new Intent(this, UpdaterService.class);
intent.setAction(ACTION_INSTALL_RESUME);
diff --git a/src/org/lineageos/updater/misc/Utils.java b/src/org/lineageos/updater/misc/Utils.java
index 497b635fa0584a9e1b06e82a28548a79d45c0097..4e7b20f209fd84ac9b9bbe83c38070c0ffe4b366 100644
--- a/src/org/lineageos/updater/misc/Utils.java
+++ b/src/org/lineageos/updater/misc/Utils.java
@@ -22,6 +22,7 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
@@ -29,6 +30,7 @@ import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.Uri;
+import android.os.BatteryManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
@@ -66,6 +68,10 @@ import java.util.zip.ZipFile;
public class Utils {
+ private static final int BATTERY_PLUGGED_ANY = BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS;
+
private static final String TAG = "Utils";
private static final String CONTENT_URI_PATH = "content://custom.setting.Provider.OTA_SERVER/cte";
@@ -507,4 +513,19 @@ public class Utils {
public static boolean isRecoveryUpdateExecPresent() {
return new File(Constants.UPDATE_RECOVERY_EXEC).exists();
}
+
+ public static boolean isBatteryLevelOk(Context context) {
+ Intent intent = context.registerReceiver(null,
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ if (!intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false)) {
+ return true;
+ }
+ int percent = Math.round(100.f * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100) /
+ intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+ int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+ int required = (plugged & BATTERY_PLUGGED_ANY) != 0 ?
+ context.getResources().getInteger(R.integer.battery_ok_percentage_charging) :
+ context.getResources().getInteger(R.integer.battery_ok_percentage_discharging);
+ return percent >= required;
+ }
}