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; }