Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5df3442b authored by Tommy Webb's avatar Tommy Webb Committed by Michael Bestas
Browse files

SystemUI: React to PrivacyConfig changes properly

Store normal callback references in PrivacyConfig, rather than
WeakReference. This prevents the callbacks from becoming phantom
reachable (finalized) shortly after SystemUI starts.

Prior to this change, devices with an overlay config to enable location
indicators may not properly utilize the indicator until the device is
rebooted at least once after first install, if the garbage collector
wins the race and finalizes the necessary PrivacyConfig callback.

Test: Manual: Boot and unlock a device and wait about a minute for it
to settle. Run `adb shell "dumpsys activity service \
com.android.systemui | grep locationAvailable"`. It will return two
results with matching values. Then, run `adb shell cmd device_config \
put privacy location_indicators_enabled false` (or `true`; whichever
does not match the value seen earlier) to change the values. Finally,
run the first adb command again to verify that both of the values for
locationAvailable match and reflect the newly-specified value.

Issue: calyxos#1648
Change-Id: I4ee1d5054a8bb294cea267034169c6615490a735
parent f726f1cc
Loading
Loading
Loading
Loading
+8 −20
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import com.android.systemui.util.asIndenting
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.withIncreasedIndent
import java.io.PrintWriter
import java.lang.ref.WeakReference
import javax.inject.Inject

@SysUISingleton
@@ -50,7 +49,7 @@ class PrivacyConfig @Inject constructor(
        private const val DEFAULT_MEDIA_PROJECTION = true
    }

    private val callbacks = mutableListOf<WeakReference<Callback>>()
    private val callbacks = mutableListOf<Callback>()

    var micCameraAvailable = isMicCameraEnabled()
        private set
@@ -65,19 +64,19 @@ class PrivacyConfig @Inject constructor(
                    // Running on the ui executor so can iterate on callbacks
                    if (properties.keyset.contains(MIC_CAMERA)) {
                        micCameraAvailable = properties.getBoolean(MIC_CAMERA, DEFAULT_MIC_CAMERA)
                        callbacks.forEach { it.get()?.onFlagMicCameraChanged(micCameraAvailable) }
                        callbacks.forEach { it.onFlagMicCameraChanged(micCameraAvailable) }
                    }

                    if (properties.keyset.contains(LOCATION)) {
                        locationAvailable = properties.getBoolean(LOCATION, DEFAULT_LOCATION)
                        callbacks.forEach { it.get()?.onFlagLocationChanged(locationAvailable) }
                        callbacks.forEach { it.onFlagLocationChanged(locationAvailable) }
                    }

                    if (properties.keyset.contains(MEDIA_PROJECTION)) {
                        mediaProjectionAvailable =
                                properties.getBoolean(MEDIA_PROJECTION, DEFAULT_MEDIA_PROJECTION)
                        callbacks.forEach {
                            it.get()?.onFlagMediaProjectionChanged(mediaProjectionAvailable)
                            it.onFlagMediaProjectionChanged(mediaProjectionAvailable)
                        }
                    }
                }
@@ -107,23 +106,14 @@ class PrivacyConfig @Inject constructor(
    }

    fun addCallback(callback: Callback) {
        addCallback(WeakReference(callback))
    }

    fun removeCallback(callback: Callback) {
        removeCallback(WeakReference(callback))
    }

    private fun addCallback(callback: WeakReference<Callback>) {
        uiExecutor.execute {
            callbacks.add(callback)
        }
    }

    private fun removeCallback(callback: WeakReference<Callback>) {
    fun removeCallback(callback: Callback) {
        uiExecutor.execute {
            // Removes also if the callback is null
            callbacks.removeIf { it.get()?.equals(callback.get()) ?: true }
            callbacks.remove(callback)
        }
    }

@@ -136,9 +126,7 @@ class PrivacyConfig @Inject constructor(
            ipw.println("mediaProjectionAvailable: $mediaProjectionAvailable")
            ipw.println("Callbacks:")
            ipw.withIncreasedIndent {
                callbacks.forEach { callback ->
                    callback.get()?.let { ipw.println(it) }
                }
                callbacks.forEach { ipw.println(it) }
            }
        }
        ipw.flush()