Loading res/values/strings.xml +3 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ <string name="downloading_notification">Downloading</string> <string name="download_paused_notification">Download paused</string> <string name="download_paused_error_notification">Download error</string> <string name="download_completed_notification">Download completed</string> <string name="download_completed_notification">Update is ready to be installed</string> <string name="download_starting_notification">Starting download</string> <string name="update_failed_notification">Update failed</string> <string name="installation_suspended_notification">Installation suspended</string> Loading @@ -52,6 +52,7 @@ <string name="pause_button">Pause</string> <string name="resume_button">Resume</string> <string name="suspend_button">Suspend</string> <string name="reboot_install">Reboot and install</string> <string name="installing_update">Installing update package</string> <string name="installing_update_error">Install error</string> Loading Loading @@ -103,6 +104,7 @@ <string name="list_no_updates">You are running the latest /e/OS version. To manually check for updates, use the Refresh button.</string> <string name="action_download">Download</string> <string name="action_update">Apply update</string> <string name="action_pause">Pause</string> <string name="action_resume">Resume</string> <string name="action_install">Install</string> Loading src/org/lineageos/updater/UpdatesListAdapter.java +7 −25 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -68,10 +66,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. private static final String TAG = "UpdateListAdapter"; private static final int BATTERY_PLUGGED_ANY = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; private final float mAlphaDisabledValue; private List<String> mDownloadIds; Loading Loading @@ -245,7 +239,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. if (update == null) { // The update was deleted viewHolder.mAction.setEnabled(false); viewHolder.mAction.setText(R.string.action_download); viewHolder.mAction.setText(Utils.isABDevice() ? R.string.action_update : R.string.action_download); return; } Loading Loading @@ -357,7 +352,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. .setTitle(R.string.update_on_mobile_data_title) .setMessage(R.string.update_on_mobile_data_message) .setView(checkboxView) .setPositiveButton(R.string.action_download, .setPositiveButton(Utils.isABDevice() ? R.string.action_update : R.string.action_download, (dialog, which) -> { if (checkbox.isChecked()) { preferences.edit() Loading @@ -376,7 +372,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. final View.OnClickListener clickListener; switch (action) { case DOWNLOAD: button.setText(R.string.action_download); button.setText(Utils.isABDevice() ? R.string.action_update : R.string.action_download); button.setEnabled(enabled); clickListener = enabled ? view -> { AlertDialog.Builder freeSpaceDialog = getSpaceDialog( Loading Loading @@ -504,7 +501,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. private AlertDialog.Builder getInstallDialog(final String downloadId) { Resources resources = mActivity.getResources(); if (!isBatteryLevelOk()) { if (!Utils.isBatteryLevelOk(mActivity)) { String message = resources.getString(R.string.dialog_battery_low_message_pct, resources.getInteger(R.integer.battery_ok_percentage_discharging), resources.getInteger(R.integer.battery_ok_percentage_charging)); Loading Loading @@ -639,19 +636,4 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. TextView textView = (TextView) infoDialog.findViewById(android.R.id.message); textView.setMovementMethod(LinkMovementMethod.getInstance()); } private boolean isBatteryLevelOk() { Intent intent = mActivity.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 ? mActivity.getResources().getInteger(R.integer.battery_ok_percentage_charging) : mActivity.getResources().getInteger(R.integer.battery_ok_percentage_discharging); return percent >= required; } } src/org/lineageos/updater/controller/UpdaterService.java +59 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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: { Loading Loading @@ -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()); /* 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: { Loading Loading @@ -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); Loading src/org/lineageos/updater/misc/Utils.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"; Loading Loading @@ -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; } } Loading
res/values/strings.xml +3 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ <string name="downloading_notification">Downloading</string> <string name="download_paused_notification">Download paused</string> <string name="download_paused_error_notification">Download error</string> <string name="download_completed_notification">Download completed</string> <string name="download_completed_notification">Update is ready to be installed</string> <string name="download_starting_notification">Starting download</string> <string name="update_failed_notification">Update failed</string> <string name="installation_suspended_notification">Installation suspended</string> Loading @@ -52,6 +52,7 @@ <string name="pause_button">Pause</string> <string name="resume_button">Resume</string> <string name="suspend_button">Suspend</string> <string name="reboot_install">Reboot and install</string> <string name="installing_update">Installing update package</string> <string name="installing_update_error">Install error</string> Loading Loading @@ -103,6 +104,7 @@ <string name="list_no_updates">You are running the latest /e/OS version. To manually check for updates, use the Refresh button.</string> <string name="action_download">Download</string> <string name="action_update">Apply update</string> <string name="action_pause">Pause</string> <string name="action_resume">Resume</string> <string name="action_install">Install</string> Loading
src/org/lineageos/updater/UpdatesListAdapter.java +7 −25 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -68,10 +66,6 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. private static final String TAG = "UpdateListAdapter"; private static final int BATTERY_PLUGGED_ANY = BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB | BatteryManager.BATTERY_PLUGGED_WIRELESS; private final float mAlphaDisabledValue; private List<String> mDownloadIds; Loading Loading @@ -245,7 +239,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. if (update == null) { // The update was deleted viewHolder.mAction.setEnabled(false); viewHolder.mAction.setText(R.string.action_download); viewHolder.mAction.setText(Utils.isABDevice() ? R.string.action_update : R.string.action_download); return; } Loading Loading @@ -357,7 +352,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. .setTitle(R.string.update_on_mobile_data_title) .setMessage(R.string.update_on_mobile_data_message) .setView(checkboxView) .setPositiveButton(R.string.action_download, .setPositiveButton(Utils.isABDevice() ? R.string.action_update : R.string.action_download, (dialog, which) -> { if (checkbox.isChecked()) { preferences.edit() Loading @@ -376,7 +372,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. final View.OnClickListener clickListener; switch (action) { case DOWNLOAD: button.setText(R.string.action_download); button.setText(Utils.isABDevice() ? R.string.action_update : R.string.action_download); button.setEnabled(enabled); clickListener = enabled ? view -> { AlertDialog.Builder freeSpaceDialog = getSpaceDialog( Loading Loading @@ -504,7 +501,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. private AlertDialog.Builder getInstallDialog(final String downloadId) { Resources resources = mActivity.getResources(); if (!isBatteryLevelOk()) { if (!Utils.isBatteryLevelOk(mActivity)) { String message = resources.getString(R.string.dialog_battery_low_message_pct, resources.getInteger(R.integer.battery_ok_percentage_discharging), resources.getInteger(R.integer.battery_ok_percentage_charging)); Loading Loading @@ -639,19 +636,4 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter. TextView textView = (TextView) infoDialog.findViewById(android.R.id.message); textView.setMovementMethod(LinkMovementMethod.getInstance()); } private boolean isBatteryLevelOk() { Intent intent = mActivity.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 ? mActivity.getResources().getInteger(R.integer.battery_ok_percentage_charging) : mActivity.getResources().getInteger(R.integer.battery_ok_percentage_discharging); return percent >= required; } }
src/org/lineageos/updater/controller/UpdaterService.java +59 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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: { Loading Loading @@ -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()); /* 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: { Loading Loading @@ -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); Loading
src/org/lineageos/updater/misc/Utils.java +21 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"; Loading Loading @@ -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; } }