Skip to content

Commit

Permalink
Improve workaround for Android 15 null network bug
Browse files Browse the repository at this point in the history
We'll now try to query the capabilities of the active network in the
fallback path so that the job will still run if the network satisfies
the unmetered network requirement.

Since the fallback path (querying the active network) is no longer
limited compared to the normal path (JobScheduler providing a valid
network), the notification telling users about the Android 15 bug has
been removed.

Signed-off-by: Andrew Gunnerson <[email protected]>
  • Loading branch information
chenxiaolong committed Nov 25, 2024
1 parent 922bbc8 commit 4f3a35d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 29 deletions.
47 changes: 22 additions & 25 deletions app/src/main/java/com/chiller3/custota/updater/UpdaterJob.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,12 @@ import android.app.job.JobService
import android.content.ComponentName
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.PersistableBundle
import android.util.Log
import androidx.annotation.StringRes
import com.chiller3.custota.Notifications
import com.chiller3.custota.Preferences
import com.chiller3.custota.R

class UpdaterJob: JobService() {
private fun notifyAlert(@StringRes messageId: Int) {
val notifications = Notifications(this)
notifications.sendAlertNotification(
Notifications.CHANNEL_ID_FAILURE,
true,
R.string.notification_update_init_failed,
R.drawable.ic_notifications,
getString(messageId),
emptyList()
)
}

override fun onStartJob(params: JobParameters): Boolean {
val prefs = Preferences(this)
val isPeriodic = params.jobId == ID_PERIODIC
Expand All @@ -51,23 +37,34 @@ class UpdaterJob: JobService() {
val action = UpdaterThread.Action.entries[actionIndex]

var network = params.network
if (network == null) {
// This was reported to happen on the Android 15 beta.
Log.w(TAG, "Job parameters contain a null network instance")
if (action.requiresNetwork && network == null) {
// Ever since the Android 15 betas, Android sometimes invokes this job with a null
// Network instance, even though the network requirement is set and a sufficient network
// is available. We'll try to work around this by manually querying the active network.
// If the active network is insufficient, we'll just abort and wait for the next
// scheduled run.

if (prefs.requireUnmetered) {
Log.w(TAG, "Aborting due to require unmetered network option")
notifyAlert(R.string.notification_null_network_fallback)
return false
}
Log.w(TAG, "Job parameters contain a null network instance")

val connectivityManager = getSystemService(ConnectivityManager::class.java)
network = connectivityManager.activeNetwork
if (network == null) {
Log.e(TAG, "Aborting due to active network also being null")
notifyAlert(R.string.notification_null_network_unavailable)
Log.w(TAG, "Aborting due to active network also being null")
return false
}

if (prefs.requireUnmetered) {
val capabilities = connectivityManager.getNetworkCapabilities(network)
if (capabilities == null) {
Log.w(TAG, "Aborting due to the network capabilities being null for: $network")
return false
}

if (!capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)) {
Log.w(TAG, "Aborting due to active network being metered: $capabilities")
return false
}
}
}

startForegroundService(UpdaterService.createStartIntent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class UpdaterService : Service(), UpdaterThread.UpdaterThreadListener {
// IntentCompat is required due to an Android 13 bug that's only fixed in 14+
// https://issuetracker.google.com/issues/274185314
val network = IntentCompat.getParcelableExtra(
intent, EXTRA_NETWORK, Network::class.java)!!
intent, EXTRA_NETWORK, Network::class.java)
val action = IntentCompat.getParcelableExtra(
intent, EXTRA_ACTION, UpdaterThread.Action::class.java)!!
val silent = intent.getBooleanExtra(EXTRA_SILENT, false)
Expand Down Expand Up @@ -359,7 +359,7 @@ class UpdaterService : Service(), UpdaterThread.UpdaterThreadListener {

fun createStartIntent(
context: Context,
network: Network,
network: Network?,
action: UpdaterThread.Action,
silent: Boolean,
) = Intent(context, UpdaterService::class.java).apply {
Expand Down
2 changes: 0 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@
<string name="notification_update_ota_cancelled">OTA update process was cancelled</string>
<string name="notification_update_ota_reverted">Successfully reverted OTA update</string>
<string name="notification_update_ota_failed">Failed to install OTA update</string>
<string name="notification_null_network_fallback">Background job network restrictions are broken in this build of Android. Disable the Require Unmetered Network option to allow using any active network.</string>
<string name="notification_null_network_unavailable">Background job network restrictions are broken in this build of Android. The background job ran despite there being no active network connection.</string>
<string name="notification_action_install">Install</string>
<string name="notification_action_pause">Pause</string>
<string name="notification_action_resume">Resume</string>
Expand Down

0 comments on commit 4f3a35d

Please sign in to comment.