diff --git a/src/org/lineageos/updater/controller/ABUpdateInstaller.java b/src/org/lineageos/updater/controller/ABUpdateInstaller.java index c8a632f..d5ccb9c 100644 --- a/src/org/lineageos/updater/controller/ABUpdateInstaller.java +++ b/src/org/lineageos/updater/controller/ABUpdateInstaller.java @@ -41,15 +41,26 @@ class ABUpdateInstaller { private static final String TAG = "ABUpdateInstaller"; - private static String sDownloadId; + private static final String PREF_INSTALLING_AB_ID = "installing_ab_id"; private final UpdaterController mUpdaterController; - private final String mDownloadId; private final Context mContext; + private String mDownloadId; + private boolean mReconnecting; + + private UpdateEngine mUpdateEngine; private final UpdateEngineCallback mUpdateEngineCallback = new UpdateEngineCallback() { + @Override public void onStatusUpdate(int status, float percent) { + Update update = mUpdaterController.getActualUpdate(mDownloadId); + if (update == null) { + // We read the id from a preference, the update could no longer exist + installationDone(); + return; + } + switch (status) { case UpdateEngine.UpdateStatusConstants.DOWNLOADING: case UpdateEngine.UpdateStatusConstants.FINALIZING: { @@ -60,8 +71,7 @@ class ABUpdateInstaller { break; case UpdateEngine.UpdateStatusConstants.REPORTING_ERROR_EVENT: { - sDownloadId = null; - Update update = mUpdaterController.getActualUpdate(mDownloadId); + installationDone(); update.setInstallProgress(0); update.setStatus(UpdateStatus.INSTALLATION_FAILED); mUpdaterController.notifyUpdateChange(mDownloadId); @@ -69,8 +79,7 @@ class ABUpdateInstaller { break; case UpdateEngine.UpdateStatusConstants.UPDATED_NEED_REBOOT: { - sDownloadId = null; - Update update = mUpdaterController.getActualUpdate(mDownloadId); + installationDone(); update.setInstallProgress(0); update.setStatus(UpdateStatus.INSTALLED); mUpdaterController.notifyUpdateChange(mDownloadId); @@ -83,6 +92,16 @@ class ABUpdateInstaller { } } break; + + case UpdateEngine.UpdateStatusConstants.IDLE: { + if (mReconnecting) { + // The service was restarted because we thought we were installing an + // update, but we aren't, so clear everything. + installationDone(); + mReconnecting = false; + } + } + break; } } @@ -91,35 +110,29 @@ class ABUpdateInstaller { } }; - static synchronized boolean start(Context context, UpdaterController updaterController, - String downloadId) { - if (sDownloadId != null) { - return false; - } - ABUpdateInstaller installer = new ABUpdateInstaller(context, updaterController, downloadId); - if (installer.startUpdate()) { - sDownloadId = downloadId; - return true; - } - return false; + static synchronized boolean isInstallingUpdate(Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getString(ABUpdateInstaller.PREF_INSTALLING_AB_ID, null) != null; } - static synchronized boolean isInstallingUpdate() { - return sDownloadId != null; + static synchronized boolean isInstallingUpdate(Context context, String downloadId) { + return downloadId.equals(PreferenceManager.getDefaultSharedPreferences(context) + .getString(ABUpdateInstaller.PREF_INSTALLING_AB_ID, null)); } - static synchronized boolean isInstallingUpdate(String downloadId) { - return sDownloadId != null && sDownloadId.equals(downloadId); - } - - private ABUpdateInstaller(Context context, UpdaterController updaterController, - String downloadId) { + ABUpdateInstaller(Context context, UpdaterController updaterController) { mUpdaterController = updaterController; - mDownloadId = downloadId; mContext = context; } - private boolean startUpdate() { + public boolean install(String downloadId) { + if (isInstallingUpdate(mContext)) { + Log.e(TAG, "Already installing an update"); + return false; + } + + mDownloadId = downloadId; + File file = mUpdaterController.getActualUpdate(mDownloadId).getFile(); if (!file.exists()) { Log.e(TAG, "The given update doesn't exist"); @@ -154,11 +167,42 @@ class ABUpdateInstaller { return false; } - UpdateEngine updateEngine = new UpdateEngine(); - updateEngine.bind(mUpdateEngineCallback); + mUpdateEngine = new UpdateEngine(); + if (!mUpdateEngine.bind(mUpdateEngineCallback)) { + Log.e(TAG, "Could not bind"); + return false; + } String zipFileUri = "file://" + file.getAbsolutePath(); - updateEngine.applyPayload(zipFileUri, offset, 0, headerKeyValuePairs); + mUpdateEngine.applyPayload(zipFileUri, offset, 0, headerKeyValuePairs); + + mUpdaterController.getActualUpdate(mDownloadId).setStatus(UpdateStatus.INSTALLING); + mUpdaterController.notifyUpdateChange(mDownloadId); + + PreferenceManager.getDefaultSharedPreferences(mContext).edit() + .putString(PREF_INSTALLING_AB_ID, mDownloadId) + .apply(); return true; } + + public boolean reconnect() { + if (!isInstallingUpdate(mContext)) { + Log.e(TAG, "reconnect: Not installing any update"); + return false; + } + + mReconnecting = true; + mDownloadId = PreferenceManager.getDefaultSharedPreferences(mContext) + .getString(PREF_INSTALLING_AB_ID, null); + + mUpdateEngine = new UpdateEngine(); + // We will get a status notification as soon as we are connected + return mUpdateEngine.bind(mUpdateEngineCallback); + } + + private void installationDone() { + PreferenceManager.getDefaultSharedPreferences(mContext).edit() + .remove(PREF_INSTALLING_AB_ID) + .apply(); + } } diff --git a/src/org/lineageos/updater/controller/UpdaterController.java b/src/org/lineageos/updater/controller/UpdaterController.java index 6ac9e26..9efa8e5 100644 --- a/src/org/lineageos/updater/controller/UpdaterController.java +++ b/src/org/lineageos/updater/controller/UpdaterController.java @@ -53,6 +53,7 @@ public class UpdaterController implements Controller { private static final int MAX_REPORT_INTERVAL_MS = 1000; + private final Context mContext; private final LocalBroadcastManager mBroadcastManager; private final UpdatesDbHelper mUpdatesDbHelper; @@ -81,6 +82,7 @@ public class UpdaterController implements Controller { PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Updater"); mWakeLock.setReferenceCounted(false); + mContext = context.getApplicationContext(); Utils.cleanupDownloadsDir(context); @@ -532,11 +534,11 @@ public class UpdaterController implements Controller { @Override public boolean isInstallingUpdate() { - return ABUpdateInstaller.isInstallingUpdate(); + return ABUpdateInstaller.isInstallingUpdate(mContext); } @Override public boolean isInstallingUpdate(String downloadId) { - return ABUpdateInstaller.isInstallingUpdate(downloadId); + return ABUpdateInstaller.isInstallingUpdate(mContext, downloadId); } } diff --git a/src/org/lineageos/updater/controller/UpdaterService.java b/src/org/lineageos/updater/controller/UpdaterService.java index 317e185..0e0d4dc 100644 --- a/src/org/lineageos/updater/controller/UpdaterService.java +++ b/src/org/lineageos/updater/controller/UpdaterService.java @@ -153,7 +153,16 @@ public class UpdaterService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - if (ACTION_DOWNLOAD_CONTROL.equals(intent.getAction())) { + Log.d(TAG, "Starting service"); + + if ((intent == null || intent.getAction() == null) && + ABUpdateInstaller.isInstallingUpdate(this)) { + // The service is being restarted. + ABUpdateInstaller installer = new ABUpdateInstaller(this, mUpdaterController); + if (installer.reconnect()) { + return START_STICKY; + } + } else if (ACTION_DOWNLOAD_CONTROL.equals(intent.getAction())) { String downloadId = intent.getStringExtra(EXTRA_DOWNLOAD_ID); int action = intent.getIntExtra(EXTRA_DOWNLOAD_CONTROL, -1); if (action == DOWNLOAD_RESUME) { @@ -171,7 +180,10 @@ public class UpdaterService extends Service { } try { if (Utils.isABUpdate(update.getFile())) { - ABUpdateInstaller.start(this, mUpdaterController, downloadId); + ABUpdateInstaller installer = new ABUpdateInstaller(this, mUpdaterController); + if (installer.install(downloadId)) { + return START_STICKY; + } } else { boolean deleteUpdate = PreferenceManager.getDefaultSharedPreferences(this) .getBoolean(Constants.PREF_AUTO_DELETE_UPDATES, false); @@ -202,7 +214,6 @@ public class UpdaterService extends Service { // TODO: user facing message } } - Log.d(TAG, "Service started"); return START_NOT_STICKY; } @@ -370,6 +381,11 @@ public class UpdaterService extends Service { tryStopSelf(); break; } + case INSTALLATION_CANCELLED: { + stopForeground(true); + tryStopSelf(); + break; + } } } diff --git a/src/org/lineageos/updater/model/UpdateStatus.java b/src/org/lineageos/updater/model/UpdateStatus.java index c8da537..d1ec67d 100644 --- a/src/org/lineageos/updater/model/UpdateStatus.java +++ b/src/org/lineageos/updater/model/UpdateStatus.java @@ -28,7 +28,8 @@ public enum UpdateStatus { VERIFICATION_FAILED, INSTALLING, INSTALLED, - INSTALLATION_FAILED; + INSTALLATION_FAILED, + INSTALLATION_CANCELLED; public static final class Persistent { public static final int UNKNOWN = 0;