diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2239482e8f87f0702a6e5743fdd419e9580bb8a5..0efe456818ddf8b015f665eda8850f7799f1be6b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -40,7 +40,7 @@
Downloading
Download paused
Download error
- Download completed
+ Update is ready to be installed
Starting download
Update failed
Installation suspended
@@ -52,6 +52,7 @@
Pause
Resume
Suspend
+ Reboot and install
Installing update package
Install error
@@ -103,6 +104,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 3e5f7c657a53ceaae62918c78b4dad8d7ac67243..e0a7d30b4529e871a9fb95f94eda17cb62ff083e 100644
--- a/src/org/lineageos/updater/UpdatesListAdapter.java
+++ b/src/org/lineageos/updater/UpdatesListAdapter.java
@@ -17,10 +17,8 @@ package org.lineageos.updater;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
-import android.os.BatteryManager;
import android.os.Build;
import android.os.PowerManager;
import android.text.SpannableString;
@@ -68,10 +66,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter mDownloadIds;
@@ -245,7 +239,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter {
if (checkbox.isChecked()) {
preferences.edit()
@@ -372,7 +368,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter {
AlertDialog.Builder freeSpaceDialog = getSpaceDialog(
@@ -500,7 +497,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 21da556f75fc9090fb57a82a9ce56225e7f87c9d..632c11b8982779c7066f5ce90e979bc74165e16a 100644
--- a/src/org/lineageos/updater/controller/UpdaterService.java
+++ b/src/org/lineageos/updater/controller/UpdaterService.java
@@ -27,6 +27,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: {
@@ -525,6 +574,14 @@ public class UpdaterService extends Service {
PendingIntent.FLAG_UPDATE_CURRENT);
}
+ 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 65369fc6ccacbef3e631eb7b94c40d06a17aa1bc..d795a7c9bf9639e69880dad3647f5cd62ee4b9a3 100644
--- a/src/org/lineageos/updater/misc/Utils.java
+++ b/src/org/lineageos/updater/misc/Utils.java
@@ -21,12 +21,14 @@ 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;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
+import android.os.BatteryManager;
import android.os.Environment;
import android.os.StatFs;
import android.os.SystemProperties;
@@ -63,6 +65,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";
@@ -486,4 +492,19 @@ public class Utils {
return AlarmManager.INTERVAL_DAY * 30;
}
}
+
+ 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;
+ }
}