Remove and delay broadcast receiver registrations [VPNAND-2484].

This commit is contained in:
Marcin Simonides
2026-02-16 17:17:03 +01:00
committed by MargeBot
parent 57d7f672a4
commit 2d886a857f
4 changed files with 58 additions and 11 deletions

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2026. Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see <https://www.gnu.org/licenses/>.
*/
package com.protonvpn.android.concurrency
import java.util.concurrent.atomic.AtomicBoolean
class Once(private val block: () -> Unit) {
private val hasRun = AtomicBoolean(false)
fun invokeOnce() {
if (hasRun.compareAndSet(false, true)) {
block()
}
}
}

View File

@@ -23,6 +23,7 @@ import android.content.Context
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.PowerManager
import com.protonvpn.android.concurrency.Once
import com.protonvpn.android.utils.AndroidUtils.registerBroadcastReceiver
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
@@ -34,7 +35,7 @@ class PowerStateLogger @Inject constructor(
private val powerManager: dagger.Lazy<PowerManager>,
private val batteryManager: dagger.Lazy<BatteryManager?>
) {
init {
private val registerBroadcastReceiver = Once {
val filter = IntentFilter().apply {
addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)
addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
@@ -48,6 +49,8 @@ class PowerStateLogger @Inject constructor(
}
fun getStatusString(): String {
registerBroadcastReceiver.invokeOnce() // Status is logged for the first time soon after app start.
val batteryManager = batteryManager.get()
val powerManager = powerManager.get()
val packageName = context.packageName

View File

@@ -81,14 +81,22 @@ class TrafficMonitor @Inject constructor(
}
}
context.registerBroadcastReceiver(IntentFilter(Intent.ACTION_SCREEN_OFF)) {
ProtonLogger.logCustom(LogCategory.UI, "Screen off")
stopUpdateJob()
val onOffFilter = IntentFilter().apply {
addAction(Intent.ACTION_SCREEN_OFF)
addAction(Intent.ACTION_SCREEN_ON)
}
context.registerBroadcastReceiver(IntentFilter(Intent.ACTION_SCREEN_ON)) {
ProtonLogger.logCustom(LogCategory.UI, "Screen on")
if (vpnStateMonitor.state == VpnState.Connected)
startUpdateJob()
context.registerBroadcastReceiver(onOffFilter) { intent ->
when (intent?.action) {
Intent.ACTION_SCREEN_OFF -> {
ProtonLogger.logCustom(LogCategory.UI, "Screen off")
stopUpdateJob()
}
Intent.ACTION_SCREEN_ON -> {
ProtonLogger.logCustom(LogCategory.UI, "Screen on")
if (vpnStateMonitor.state == VpnState.Connected)
startUpdateJob()
}
}
}
}

View File

@@ -35,6 +35,7 @@ import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.protonvpn.android.R
import com.protonvpn.android.concurrency.Once
import com.protonvpn.android.ui.storage.UiStateStorage
import com.protonvpn.android.utils.AndroidUtils.registerBroadcastReceiver
import com.protonvpn.android.widget.data.WidgetTracker
@@ -80,6 +81,11 @@ class WidgetManager @Inject constructor(
val WIDGET_ADDED_ACTION = "intent.action.WIDGET_ADDED";
}
private val registerOnAddedReceiver = Once {
context.registerBroadcastReceiver(IntentFilter(WIDGET_ADDED_ACTION)) {
Toast.makeText(context, R.string.widget_toast_added_message, Toast.LENGTH_SHORT).show()
}
}
private val hasAddedWidget: StateFlow<Boolean?> = widgetTracker.haveWidgets
@@ -116,9 +122,6 @@ class WidgetManager @Inject constructor(
}
}
}
context.registerBroadcastReceiver(IntentFilter(WIDGET_ADDED_ACTION)) {
Toast.makeText(context, R.string.widget_toast_added_message, Toast.LENGTH_SHORT).show()
}
}
@TargetApi(26)
@@ -160,6 +163,7 @@ class WidgetManager @Inject constructor(
null,
successPendingIntent
)
registerOnAddedReceiver.invokeOnce()
} catch (_: IllegalStateException) {
// The app is not in foreground - this can happen rarely if the app goes to background right after user
// taps the button.