diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2c1443db..b5718460 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -41,6 +41,7 @@
Download error
Download completed
Starting download
+ Update failed
New updates
diff --git a/src/org/lineageos/updater/UpdaterReceiver.java b/src/org/lineageos/updater/UpdaterReceiver.java
index ca099144..f50343d8 100644
--- a/src/org/lineageos/updater/UpdaterReceiver.java
+++ b/src/org/lineageos/updater/UpdaterReceiver.java
@@ -15,20 +15,65 @@
*/
package org.lineageos.updater;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.PowerManager;
+import android.os.SystemProperties;
+import android.support.v4.app.NotificationCompat;
import android.support.v7.preference.PreferenceManager;
+import org.lineageos.updater.misc.BuildInfoUtils;
import org.lineageos.updater.misc.Constants;
+import org.lineageos.updater.misc.StringGenerator;
+
+import java.text.DateFormat;
public class UpdaterReceiver extends BroadcastReceiver {
public static final String ACTION_INSTALL_REBOOT =
"org.lineageos.updater.action.INSTALL_REBOOT";
+ private static boolean shouldShowUpdateFailedNotification(Context context) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+
+ // We can't easily detect failed re-installations
+ if (preferences.getBoolean(Constants.PREF_INSTALL_AGAIN, false) ||
+ preferences.getBoolean(Constants.PREF_INSTALL_NOTIFIED, false)) {
+ return false;
+ }
+
+ long buildTimestamp = SystemProperties.getLong(Constants.PROP_BUILD_DATE, 0);
+ long lastBuildTimestamp = preferences.getLong(Constants.PREF_INSTALL_OLD_TIMESTAMP, -1);
+ return buildTimestamp == lastBuildTimestamp;
+ }
+
+ private static void showUpdateFailedNotification(Context context) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+ String buildDate = StringGenerator.getDateLocalizedUTC(context,
+ DateFormat.MEDIUM, preferences.getLong(Constants.PREF_INSTALL_NEW_TIMESTAMP, 0));
+ String buildInfo = context.getString(R.string.list_build_version_date,
+ BuildInfoUtils.getBuildVersion(), buildDate);
+
+ Intent notificationIntent = new Intent(context, UpdatesActivity.class);
+ PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
+ .setContentIntent(intent)
+ .setSmallIcon(R.drawable.ic_system_update)
+ .setContentTitle(context.getString(R.string.update_failed_notification))
+ .setStyle(new NotificationCompat.BigTextStyle().bigText(buildInfo))
+ .setContentText(buildInfo);
+
+ NotificationManager nm = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ nm.notify(0, builder.build());
+ }
+
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_INSTALL_REBOOT.equals(intent.getAction())) {
@@ -37,6 +82,11 @@ public class UpdaterReceiver extends BroadcastReceiver {
} else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
pref.edit().remove(Constants.PREF_NEEDS_REBOOT).apply();
+
+ if (shouldShowUpdateFailedNotification(context)) {
+ pref.edit().putBoolean(Constants.PREF_INSTALL_NOTIFIED, true).apply();
+ showUpdateFailedNotification(context);
+ }
}
}
}
diff --git a/src/org/lineageos/updater/controller/UpdateInstaller.java b/src/org/lineageos/updater/controller/UpdateInstaller.java
index aaae06b9..ccac1c92 100644
--- a/src/org/lineageos/updater/controller/UpdateInstaller.java
+++ b/src/org/lineageos/updater/controller/UpdateInstaller.java
@@ -16,7 +16,9 @@
package org.lineageos.updater.controller;
import android.content.Context;
+import android.content.SharedPreferences;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.support.v7.preference.PreferenceManager;
import android.util.Log;
@@ -55,15 +57,20 @@ class UpdateInstaller {
void install(String downloadId) {
UpdateInfo update = mUpdaterController.getUpdate(downloadId);
- boolean deleteUpdate = PreferenceManager.getDefaultSharedPreferences(mContext)
- .getBoolean(Constants.PREF_AUTO_DELETE_UPDATES, false);
- if (deleteUpdate) {
- // Renaming the file is enough to have it deleted automatically
- File uncrytpFile = new File(
- update.getFile().getAbsolutePath() + Constants.UNCRYPT_FILE_EXT);
- update.getFile().renameTo(uncrytpFile);
- installPackage(uncrytpFile, downloadId);
- } else if (Utils.isEncrypted(mContext, update.getFile())) {
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
+ long buildTimestamp = SystemProperties.getLong(Constants.PROP_BUILD_DATE, 0);
+ long lastBuildTimestamp = preferences.getLong(Constants.PREF_INSTALL_OLD_TIMESTAMP,
+ buildTimestamp);
+ boolean isReinstalling = buildTimestamp == lastBuildTimestamp;
+ preferences.edit()
+ .putLong(Constants.PREF_INSTALL_OLD_TIMESTAMP, buildTimestamp)
+ .putLong(Constants.PREF_INSTALL_NEW_TIMESTAMP, update.getTimestamp())
+ .putString(Constants.PREF_INSTALL_PACKAGE_PATH, update.getFile().getAbsolutePath())
+ .putBoolean(Constants.PREF_INSTALL_AGAIN, isReinstalling)
+ .putBoolean(Constants.PREF_INSTALL_NOTIFIED, false)
+ .apply();
+
+ if (Utils.isEncrypted(mContext, update.getFile())) {
// uncrypt rewrites the file so that it can be read without mounting
// the filesystem, so create a copy of it.
prepareForUncryptAndInstall(update);
diff --git a/src/org/lineageos/updater/misc/Constants.java b/src/org/lineageos/updater/misc/Constants.java
index 6318874a..3ea4d22a 100644
--- a/src/org/lineageos/updater/misc/Constants.java
+++ b/src/org/lineageos/updater/misc/Constants.java
@@ -39,4 +39,9 @@ public final class Constants {
public static final String PROP_RELEASE_TYPE = "ro.cm.releasetype";
public static final String PROP_UPDATER_URI = "cm.updater.uri";
+ public static final String PREF_INSTALL_OLD_TIMESTAMP = "install_old_timestamp";
+ public static final String PREF_INSTALL_NEW_TIMESTAMP = "install_new_timestamp";
+ 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";
}
diff --git a/src/org/lineageos/updater/misc/Utils.java b/src/org/lineageos/updater/misc/Utils.java
index 255b750e..67895daf 100644
--- a/src/org/lineageos/updater/misc/Utils.java
+++ b/src/org/lineageos/updater/misc/Utils.java
@@ -264,11 +264,26 @@ public class Utils {
*/
public static void cleanupDownloadsDir(Context context) {
File downloadPath = getDownloadPath(context);
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
removeUncryptFiles(downloadPath);
+ long buildTimestamp = SystemProperties.getLong(Constants.PROP_BUILD_DATE, 0);
+ long prevTimestamp = preferences.getLong(Constants.PREF_INSTALL_OLD_TIMESTAMP, 0);
+ String lastUpdatePath = preferences.getString(Constants.PREF_INSTALL_PACKAGE_PATH, null);
+ boolean reinstalling = preferences.getBoolean(Constants.PREF_INSTALL_AGAIN, false);
+ boolean deleteUpdates = preferences.getBoolean(Constants.PREF_AUTO_DELETE_UPDATES, false);
+ if ((buildTimestamp != prevTimestamp || reinstalling) && deleteUpdates &&
+ lastUpdatePath != null) {
+ File lastUpdate = new File(lastUpdatePath);
+ if (lastUpdate.exists()) {
+ lastUpdate.delete();
+ // Remove the pref not to delete the file if re-downloaded
+ preferences.edit().remove(Constants.PREF_INSTALL_PACKAGE_PATH).apply();
+ }
+ }
+
final String DOWNLOADS_CLEANUP_DONE = "cleanup_done";
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences.getBoolean(DOWNLOADS_CLEANUP_DONE, false)) {
return;
}