From 1b60a95b75ff74535b4397572685cd50e807fdf5 Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 7 Nov 2022 14:45:44 +0530 Subject: [PATCH 1/5] Updater: add additional intervals for debug Change-Id: Iddbb5da58cc5a8d7caca627a6747ccd8fe791c3c --- res/layout/preferences_dialog.xml | 3 +-- res/values/arrays.xml | 6 ++++++ res/values/strings.xml | 3 +++ .../lineageos/updater/UpdatesActivity.java | 20 +++++++++++++++++++ src/org/lineageos/updater/misc/Constants.java | 3 +++ src/org/lineageos/updater/misc/Utils.java | 13 ++++++++++++ 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/res/layout/preferences_dialog.xml b/res/layout/preferences_dialog.xml index c586f44e..2537dccb 100644 --- a/res/layout/preferences_dialog.xml +++ b/res/layout/preferences_dialog.xml @@ -25,8 +25,7 @@ android:id="@+id/preferences_auto_updates_check_interval" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_weight="1" - android:entries="@array/menu_auto_updates_check_interval_entries" /> + android:layout_weight="1" /> @string/menu_auto_updates_check_interval_weekly @string/menu_auto_updates_check_interval_monthly + + + @string/menu_auto_updates_check_interval_5_minutes + @string/menu_auto_updates_check_interval_10_minutes + @string/menu_auto_updates_check_interval_30_minutes + diff --git a/res/values/strings.xml b/res/values/strings.xml index ac7427af..a11e7439 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -67,6 +67,9 @@ Refresh Preferences Auto updates check + Every 5 minutes + Every 10 minutes + Every 30 minutes Once a day Once a week Once a month diff --git a/src/org/lineageos/updater/UpdatesActivity.java b/src/org/lineageos/updater/UpdatesActivity.java index b27afc35..408aff15 100644 --- a/src/org/lineageos/updater/UpdatesActivity.java +++ b/src/org/lineageos/updater/UpdatesActivity.java @@ -41,6 +41,7 @@ import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; +import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; @@ -75,6 +76,7 @@ import org.lineageos.updater.model.UpdateInfo; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -491,7 +493,25 @@ public class UpdatesActivity extends UpdatesListActivity { } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + + List intervalList = new ArrayList<>(Arrays.asList(getResources().getStringArray( + R.array.menu_auto_updates_check_interval_entries))); + + if (Utils.isDevModeOn(this)) { + // Add additional intervals while enabling developer options is on + intervalList.addAll(Arrays.asList(getResources().getStringArray( + R.array.menu_auto_updates_check_interval_entries_dev))); + } else if (Utils.getUpdateCheckSetting(this) > 3) { + prefs.edit().putInt(Constants.PREF_AUTO_UPDATES_CHECK_INTERVAL, + Constants.AUTO_UPDATES_CHECK_INTERVAL_DAILY).apply(); + } + + ArrayAdapter adapter = new ArrayAdapter<>(this, + android.R.layout.simple_list_item_1, intervalList); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + autoCheckInterval.setAdapter(adapter); autoCheckInterval.setSelection(Utils.getUpdateCheckSetting(this)); + autoDelete.setChecked(prefs.getBoolean(Constants.PREF_AUTO_DELETE_UPDATES, true)); dataWarning.setChecked(prefs.getBoolean(Constants.PREF_MOBILE_DATA_WARNING, true)); abPerfMode.setChecked(prefs.getBoolean(Constants.PREF_AB_PERF_MODE, false)); diff --git a/src/org/lineageos/updater/misc/Constants.java b/src/org/lineageos/updater/misc/Constants.java index 96c0b015..0aff4ce5 100644 --- a/src/org/lineageos/updater/misc/Constants.java +++ b/src/org/lineageos/updater/misc/Constants.java @@ -27,6 +27,9 @@ public final class Constants { public static final int AUTO_UPDATES_CHECK_INTERVAL_DAILY = 1; public static final int AUTO_UPDATES_CHECK_INTERVAL_WEEKLY = 2; public static final int AUTO_UPDATES_CHECK_INTERVAL_MONTHLY = 3; + public static final int AUTO_UPDATES_CHECK_INTERVAL_5_MINUTES = 4; + public static final int AUTO_UPDATES_CHECK_INTERVAL_10_MINUTES = 5; + public static final int AUTO_UPDATES_CHECK_INTERVAL_30_MINUTES = 6; public static final String PREF_LAST_UPDATE_CHECK = "last_update_check"; public static final String PREF_AUTO_UPDATES_CHECK_INTERVAL = "auto_updates_check_interval"; diff --git a/src/org/lineageos/updater/misc/Utils.java b/src/org/lineageos/updater/misc/Utils.java index c33bb081..ec40230f 100644 --- a/src/org/lineageos/updater/misc/Utils.java +++ b/src/org/lineageos/updater/misc/Utils.java @@ -39,6 +39,7 @@ import android.os.PersistableBundle; import android.os.SystemProperties; import android.os.SystemUpdateManager; import android.os.storage.StorageManager; +import android.provider.Settings; import android.util.Log; import android.widget.Toast; @@ -456,6 +457,12 @@ public class Utils { return isAB; } + public static boolean isDevModeOn(Context context) { + int devOptions = Settings.Secure.getInt(context.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0); + return devOptions == 1; + } + public static boolean hasTouchscreen(Context context) { return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN); } @@ -486,6 +493,12 @@ public class Utils { public static long getUpdateCheckInterval(Context context) { switch (Utils.getUpdateCheckSetting(context)) { + case Constants.AUTO_UPDATES_CHECK_INTERVAL_5_MINUTES: + return AlarmManager.INTERVAL_FIFTEEN_MINUTES / 3; + case Constants.AUTO_UPDATES_CHECK_INTERVAL_10_MINUTES: + return AlarmManager.INTERVAL_HALF_HOUR / 3; + case Constants.AUTO_UPDATES_CHECK_INTERVAL_30_MINUTES: + return AlarmManager.INTERVAL_HALF_HOUR; case Constants.AUTO_UPDATES_CHECK_INTERVAL_DAILY: return AlarmManager.INTERVAL_DAY; case Constants.AUTO_UPDATES_CHECK_INTERVAL_WEEKLY: -- GitLab From 062616de0fe4112e46d3d8bf355b4df1f4fb7298 Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 7 Nov 2022 23:36:49 +0530 Subject: [PATCH 2/5] Updater: Add network ConnectionStateMonitor Change-Id: I54847a54e1cb0bff262deb3e57cae30fcd85b26f Updater: Move ConnectionStateMonitor to kotlin Change-Id: I7e0a1f68b71afe620706813daf76258b0c1682ae Updater: Improve ConnectionStateMonitor behaviour - Keep updater app alive till device back online for network callback. - Remove network callback once the internet is back. - Wait 10 seconds before doing anything when the device is online. Change-Id: I55e631cbf6cec9c19ec13e513a54ceaf10f8b2b9 --- Android.bp | 6 +- build.gradle | 5 +- .../updater/UpdatesCheckReceiver.java | 12 ++- .../updater/controller/UpdaterService.java | 4 +- .../updater/misc/ConnectionStateMonitor.kt | 92 +++++++++++++++++++ src/org/lineageos/updater/misc/Constants.java | 1 + 6 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 src/org/lineageos/updater/misc/ConnectionStateMonitor.kt diff --git a/Android.bp b/Android.bp index 7b072fc8..55ec76cf 100644 --- a/Android.bp +++ b/Android.bp @@ -20,12 +20,16 @@ android_app { // Include SettingsLib and its dependencies defaults: ["SettingsLibDefaults"], - srcs: ["src/**/*.java"], + srcs: [ + "src/**/*.java", + "src/**/*.kt", + ], resource_dirs: ["res"], static_libs: [ "com.google.android.material_material", "androidx.core_core", + "androidx.core_core-ktx", "androidx.appcompat_appcompat", "androidx.cardview_cardview", "androidx.localbroadcastmanager_localbroadcastmanager", diff --git a/build.gradle b/build.gradle index 3a2eb827..7c5e5a03 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.1.1' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10" } } @@ -19,6 +20,7 @@ def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) apply plugin: 'com.android.application' +apply plugin: 'org.jetbrains.kotlin.android' android { compileSdkVersion 31 @@ -58,9 +60,10 @@ android { dependencies { compileOnly fileTree(dir: 'system_libs/', include: ['*.jar']) - implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.2.1' + implementation 'com.google.android.material:material:1.4.0' } diff --git a/src/org/lineageos/updater/UpdatesCheckReceiver.java b/src/org/lineageos/updater/UpdatesCheckReceiver.java index 07beb1a7..87c6d341 100644 --- a/src/org/lineageos/updater/UpdatesCheckReceiver.java +++ b/src/org/lineageos/updater/UpdatesCheckReceiver.java @@ -31,6 +31,7 @@ import androidx.preference.PreferenceManager; import org.json.JSONException; import org.lineageos.updater.download.DownloadClient; +import org.lineageos.updater.misc.ConnectionStateMonitor; import org.lineageos.updater.misc.Constants; import org.lineageos.updater.misc.Utils; @@ -51,6 +52,9 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { + final ConnectionStateMonitor cnState = + new ConnectionStateMonitor(context); + if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { Utils.cleanupDownloadsDir(context); } @@ -65,12 +69,16 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { // Set a repeating alarm on boot to check for new updates once per day scheduleRepeatingUpdatesCheck(context); + cnState.setNetworkCallbackActive(false); } if (!Utils.isNetworkAvailable(context)) { - Log.d(TAG, "Network not available, scheduling new check"); - scheduleUpdatesCheck(context); + if (!cnState.isNetworkCallbackActive()) { + cnState.setupNetworkCallback(true); + } return; + } else if (cnState.isNetworkCallbackActive()) { + cnState.setupNetworkCallback(false); } final File json = Utils.getCachedUpdateList(context); diff --git a/src/org/lineageos/updater/controller/UpdaterService.java b/src/org/lineageos/updater/controller/UpdaterService.java index c0354f92..f5ed4c0b 100644 --- a/src/org/lineageos/updater/controller/UpdaterService.java +++ b/src/org/lineageos/updater/controller/UpdaterService.java @@ -42,6 +42,7 @@ import org.lineageos.updater.R; import org.lineageos.updater.UpdaterReceiver; import org.lineageos.updater.UpdatesActivity; import org.lineageos.updater.misc.BuildInfoUtils; +import org.lineageos.updater.misc.ConnectionStateMonitor; import org.lineageos.updater.misc.Constants; import org.lineageos.updater.misc.StringGenerator; import org.lineageos.updater.misc.Utils; @@ -248,8 +249,9 @@ public class UpdaterService extends Service { } private void tryStopSelf() { + ConnectionStateMonitor cnState = new ConnectionStateMonitor(this); if (!mHasClients && !mUpdaterController.hasActiveDownloads() && - !mUpdaterController.isInstallingUpdate()) { + !mUpdaterController.isInstallingUpdate() && !cnState.isNetworkCallbackActive()) { Log.d(TAG, "Service no longer needed, stopping"); stopSelf(); } diff --git a/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt b/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt new file mode 100644 index 00000000..c8246b1c --- /dev/null +++ b/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2022 MURENA SAS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.lineageos.updater.misc + +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkRequest +import android.os.Handler +import android.os.Looper +import android.util.Log +import androidx.preference.PreferenceManager + +import org.lineageos.updater.UpdatesCheckReceiver + +class ConnectionStateMonitor(private val mContext: Context) : ConnectivityManager.NetworkCallback() { + private val networkRequest: NetworkRequest = NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) + .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build() + private val pref: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext) + + fun isNetworkCallbackActive(): Boolean { + return pref.getBoolean(Constants.PREF_NETWORK_CALLBACK_ACTIVE, false) + } + + fun setNetworkCallbackActive(shouldEnable: Boolean) { + pref.edit().putBoolean(Constants.PREF_NETWORK_CALLBACK_ACTIVE, shouldEnable).apply() + } + + fun setupNetworkCallback(shouldEnable: Boolean) { + val connectivityManager: ConnectivityManager = + mContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + if (shouldEnable) { + connectivityManager.registerNetworkCallback(networkRequest, this) + } else { + try { + connectivityManager.unregisterNetworkCallback(this) + } catch (e: IllegalArgumentException) { + Log.e(tag, "Network callback was not registered") + } + } + + setNetworkCallbackActive(shouldEnable) + Log.d(tag, "Network callback enabled: $shouldEnable") + } + + private fun startUpdatesCheckReceiver(): Runnable = Runnable { + val broadcastIntent = Intent() + broadcastIntent.setClassName(mContext, UpdatesCheckReceiver::class.java.name) + mContext.sendBroadcast(broadcastIntent) + } + + private fun checkForUpdates() { + // Delay because some phones takes time go online + Handler(Looper.getMainLooper()).postDelayed( + startUpdatesCheckReceiver(), delayExecute) + } + + override fun onAvailable(network: Network) { + Log.d(tag, "Network available") + checkForUpdates() + } + + override fun onLost(network: Network) { + Log.d(tag, "Network not available") + checkForUpdates() + } + + companion object { + private const val tag = "ConnectionStateMonitor" + private const val delayExecute = 10000L // 10 seconds + } +} diff --git a/src/org/lineageos/updater/misc/Constants.java b/src/org/lineageos/updater/misc/Constants.java index 0aff4ce5..6a0f02c3 100644 --- a/src/org/lineageos/updater/misc/Constants.java +++ b/src/org/lineageos/updater/misc/Constants.java @@ -37,6 +37,7 @@ public final class Constants { public static final String PREF_AB_PERF_MODE = "ab_perf_mode"; public static final String PREF_MOBILE_DATA_WARNING = "pref_mobile_data_warning"; public static final String PREF_NEEDS_REBOOT_ID = "needs_reboot_id"; + public static final String PREF_NETWORK_CALLBACK_ACTIVE = "pref_network_callback_active"; public static final String UNCRYPT_FILE_EXT = ".uncrypt"; -- GitLab From 534048eeceff6c81ebe825677036a6ce0c2a9818 Mon Sep 17 00:00:00 2001 From: althafvly Date: Wed, 9 Nov 2022 13:49:47 +0530 Subject: [PATCH 3/5] Updater: Change one-shot check to 15 minutes - It was two hours previously Change-Id: I4fb4ae38805cedecbbd3bc86c930dfb4c3c11cc6 --- src/org/lineageos/updater/UpdatesCheckReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/lineageos/updater/UpdatesCheckReceiver.java b/src/org/lineageos/updater/UpdatesCheckReceiver.java index 87c6d341..b87366e8 100644 --- a/src/org/lineageos/updater/UpdatesCheckReceiver.java +++ b/src/org/lineageos/updater/UpdatesCheckReceiver.java @@ -189,7 +189,7 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { } public static void scheduleUpdatesCheck(Context context) { - long millisToNextCheck = AlarmManager.INTERVAL_HOUR * 2; + long millisToNextCheck = AlarmManager.INTERVAL_FIFTEEN_MINUTES; PendingIntent updateCheckIntent = getUpdatesCheckIntent(context); AlarmManager alarmMgr = context.getSystemService(AlarmManager.class); alarmMgr.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, -- GitLab From 5125ed8e5e1fd4376e8150e9271c8522afd8a8ec Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 7 Nov 2022 13:47:39 +0530 Subject: [PATCH 4/5] Updater: UpdatesCheckReceiver: Make exact alarm work every time Change-Id: Id950e6c4f44a445f78be60416e159045d120152e --- .../updater/UpdatesCheckReceiver.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/org/lineageos/updater/UpdatesCheckReceiver.java b/src/org/lineageos/updater/UpdatesCheckReceiver.java index b87366e8..c7064f00 100644 --- a/src/org/lineageos/updater/UpdatesCheckReceiver.java +++ b/src/org/lineageos/updater/UpdatesCheckReceiver.java @@ -57,6 +57,7 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { Utils.cleanupDownloadsDir(context); + cnState.setNetworkCallbackActive(false); } final SharedPreferences preferences = @@ -66,11 +67,9 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { return; } - if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { - // Set a repeating alarm on boot to check for new updates once per day - scheduleRepeatingUpdatesCheck(context); - cnState.setNetworkCallbackActive(false); - } + // Exact alarms does not support repeating, so update to make it + // work like repeating alarms. To check for update at the exact time. + updateRepeatingUpdatesCheck(context); if (!Utils.isNetworkAvailable(context)) { if (!cnState.isNetworkCallbackActive()) { @@ -168,12 +167,10 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { PendingIntent updateCheckIntent = getRepeatingUpdatesCheckIntent(context); AlarmManager alarmMgr = context.getSystemService(AlarmManager.class); - alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC, - System.currentTimeMillis() + Utils.getUpdateCheckInterval(context), - updateCheckIntent); + long nextCheck = System.currentTimeMillis() + Utils.getUpdateCheckInterval(context); + alarmMgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nextCheck, updateCheckIntent); - Date nextCheckDate = new Date(System.currentTimeMillis() + - Utils.getUpdateCheckInterval(context)); + Date nextCheckDate = new Date(nextCheck); Log.d(TAG, "Setting automatic updates check: " + nextCheckDate); } @@ -192,11 +189,11 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { long millisToNextCheck = AlarmManager.INTERVAL_FIFTEEN_MINUTES; PendingIntent updateCheckIntent = getUpdatesCheckIntent(context); AlarmManager alarmMgr = context.getSystemService(AlarmManager.class); + long nextCheck = SystemClock.elapsedRealtime() + millisToNextCheck; alarmMgr.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, - SystemClock.elapsedRealtime() + millisToNextCheck, - updateCheckIntent); + nextCheck, updateCheckIntent); - Date nextCheckDate = new Date(System.currentTimeMillis() + millisToNextCheck); + Date nextCheckDate = new Date(nextCheck); Log.d(TAG, "Setting one-shot updates check: " + nextCheckDate); } -- GitLab From 0f47e5a625ef4ddbe33a0491f91dda2f4f400539 Mon Sep 17 00:00:00 2001 From: althafvly Date: Tue, 22 Nov 2022 16:29:08 +0530 Subject: [PATCH 5/5] Updater: Simplify activity status for cnstate monitor Change-Id: I1a46444c35ce40c967a16cc8a5ae2d099e14d62e --- .../updater/UpdatesCheckReceiver.java | 44 +++++++-- .../updater/controller/UpdaterService.java | 11 ++- .../updater/misc/ConnectionStateMonitor.kt | 89 ++++++++----------- 3 files changed, 79 insertions(+), 65 deletions(-) diff --git a/src/org/lineageos/updater/UpdatesCheckReceiver.java b/src/org/lineageos/updater/UpdatesCheckReceiver.java index c7064f00..d16e9c5b 100644 --- a/src/org/lineageos/updater/UpdatesCheckReceiver.java +++ b/src/org/lineageos/updater/UpdatesCheckReceiver.java @@ -23,6 +23,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.os.SystemClock; import android.util.Log; @@ -30,6 +33,7 @@ import androidx.core.app.NotificationCompat; import androidx.preference.PreferenceManager; import org.json.JSONException; +import org.lineageos.updater.controller.UpdaterService; import org.lineageos.updater.download.DownloadClient; import org.lineageos.updater.misc.ConnectionStateMonitor; import org.lineageos.updater.misc.Constants; @@ -50,14 +54,19 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { private static final String NEW_UPDATES_NOTIFICATION_CHANNEL = "new_updates_notification_channel"; + private final NetworkRequest networkRequest = new NetworkRequest.Builder() + .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) + .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) + .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) + .build(); + + private ConnectivityManager.NetworkCallback cnState; + private ConnectivityManager connectivityManager; + @Override public void onReceive(final Context context, Intent intent) { - final ConnectionStateMonitor cnState = - new ConnectionStateMonitor(context); - if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) { Utils.cleanupDownloadsDir(context); - cnState.setNetworkCallbackActive(false); } final SharedPreferences preferences = @@ -71,13 +80,17 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { // work like repeating alarms. To check for update at the exact time. updateRepeatingUpdatesCheck(context); + cnState = new ConnectionStateMonitor().getInstance(context); + connectivityManager = (ConnectivityManager) + context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (!Utils.isNetworkAvailable(context)) { - if (!cnState.isNetworkCallbackActive()) { - cnState.setupNetworkCallback(true); + if (!UpdaterService.isNetworkCallBackActive()) { + setupNetworkCallback(true); } return; - } else if (cnState.isNetworkCallbackActive()) { - cnState.setupNetworkCallback(false); + } else if (UpdaterService.isNetworkCallBackActive()) { + setupNetworkCallback(false); } final File json = Utils.getCachedUpdateList(context); @@ -129,6 +142,21 @@ public class UpdatesCheckReceiver extends BroadcastReceiver { } } + public void setupNetworkCallback(boolean shouldEnable) { + if (shouldEnable) { + connectivityManager.registerNetworkCallback(networkRequest, cnState); + } else { + try { + connectivityManager.unregisterNetworkCallback(cnState); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Network callback was not registered"); + } + } + + UpdaterService.setNetworkCallBackActive(shouldEnable); + Log.d(TAG, "Network callback enabled: " + shouldEnable); + } + private static void showNotification(Context context) { NotificationManager notificationManager = context.getSystemService( NotificationManager.class); diff --git a/src/org/lineageos/updater/controller/UpdaterService.java b/src/org/lineageos/updater/controller/UpdaterService.java index f5ed4c0b..90544c4e 100644 --- a/src/org/lineageos/updater/controller/UpdaterService.java +++ b/src/org/lineageos/updater/controller/UpdaterService.java @@ -42,7 +42,6 @@ import org.lineageos.updater.R; import org.lineageos.updater.UpdaterReceiver; import org.lineageos.updater.UpdatesActivity; import org.lineageos.updater.misc.BuildInfoUtils; -import org.lineageos.updater.misc.ConnectionStateMonitor; import org.lineageos.updater.misc.Constants; import org.lineageos.updater.misc.StringGenerator; import org.lineageos.updater.misc.Utils; @@ -75,6 +74,7 @@ public class UpdaterService extends Service { private static final int NOTIFICATION_ID = 10; private final IBinder mBinder = new LocalBinder(); + private static boolean isNetworkCallBackActive = false; private boolean mHasClients; private BroadcastReceiver mBroadcastReceiver; @@ -249,9 +249,8 @@ public class UpdaterService extends Service { } private void tryStopSelf() { - ConnectionStateMonitor cnState = new ConnectionStateMonitor(this); if (!mHasClients && !mUpdaterController.hasActiveDownloads() && - !mUpdaterController.isInstallingUpdate() && !cnState.isNetworkCallbackActive()) { + !mUpdaterController.isInstallingUpdate() && !isNetworkCallBackActive()) { Log.d(TAG, "Service no longer needed, stopping"); stopSelf(); } @@ -475,6 +474,12 @@ public class UpdaterService extends Service { } } + public static void setNetworkCallBackActive(boolean isActive) { + isNetworkCallBackActive = isActive; + } + + public static boolean isNetworkCallBackActive() { return isNetworkCallBackActive; } + private void handleDownloadProgressChange(UpdateInfo update) { int progress = update.getProgress(); mNotificationBuilder.setProgress(100, progress, false); diff --git a/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt b/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt index c8246b1c..583d770c 100644 --- a/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt +++ b/src/org/lineageos/updater/misc/ConnectionStateMonitor.kt @@ -17,76 +17,57 @@ package org.lineageos.updater.misc import android.content.Context import android.content.Intent -import android.content.SharedPreferences import android.net.ConnectivityManager import android.net.Network -import android.net.NetworkCapabilities -import android.net.NetworkRequest import android.os.Handler import android.os.Looper import android.util.Log -import androidx.preference.PreferenceManager - import org.lineageos.updater.UpdatesCheckReceiver -class ConnectionStateMonitor(private val mContext: Context) : ConnectivityManager.NetworkCallback() { - private val networkRequest: NetworkRequest = NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .build() - private val pref: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext) - - fun isNetworkCallbackActive(): Boolean { - return pref.getBoolean(Constants.PREF_NETWORK_CALLBACK_ACTIVE, false) - } - - fun setNetworkCallbackActive(shouldEnable: Boolean) { - pref.edit().putBoolean(Constants.PREF_NETWORK_CALLBACK_ACTIVE, shouldEnable).apply() +class ConnectionStateMonitor { + companion object { + private var instance: ConnectivityManager.NetworkCallback? = null } - fun setupNetworkCallback(shouldEnable: Boolean) { - val connectivityManager: ConnectivityManager = - mContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - - if (shouldEnable) { - connectivityManager.registerNetworkCallback(networkRequest, this) - } else { - try { - connectivityManager.unregisterNetworkCallback(this) - } catch (e: IllegalArgumentException) { - Log.e(tag, "Network callback was not registered") - } + fun getInstance(context: Context): ConnectivityManager.NetworkCallback { + if (instance == null) { + instance = networkCallback(context) } - setNetworkCallbackActive(shouldEnable) - Log.d(tag, "Network callback enabled: $shouldEnable") + return instance!! } - private fun startUpdatesCheckReceiver(): Runnable = Runnable { - val broadcastIntent = Intent() - broadcastIntent.setClassName(mContext, UpdatesCheckReceiver::class.java.name) - mContext.sendBroadcast(broadcastIntent) - } + /** + * API callbacks to determine which status we currently in + * we need the below callbacks: + * - onAvailable: device connected to a network of course + * - onLost: when the connection completely lost + */ + fun networkCallback(context: Context) = object: ConnectivityManager.NetworkCallback() { + private val tag = "ConnectionStateMonitor" + private val delayExecute = 10000L // 10 seconds - private fun checkForUpdates() { - // Delay because some phones takes time go online - Handler(Looper.getMainLooper()).postDelayed( - startUpdatesCheckReceiver(), delayExecute) - } + private fun startUpdatesCheckReceiver(): Runnable = Runnable { + val broadcastIntent = Intent() + broadcastIntent.setClassName(context, UpdatesCheckReceiver::class.java.name) + context.sendBroadcast(broadcastIntent) + } - override fun onAvailable(network: Network) { - Log.d(tag, "Network available") - checkForUpdates() - } + private fun checkForUpdates() { + // Delay because some phones takes time go online + Handler(Looper.getMainLooper()).postDelayed( + startUpdatesCheckReceiver(), delayExecute + ) + } - override fun onLost(network: Network) { - Log.d(tag, "Network not available") - checkForUpdates() - } + override fun onAvailable(network: Network) { + Log.d(tag, "Network available") + checkForUpdates() + } - companion object { - private const val tag = "ConnectionStateMonitor" - private const val delayExecute = 10000L // 10 seconds + override fun onLost(network: Network) { + Log.d(tag, "Network not available") + checkForUpdates() + } } } -- GitLab