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

Commit 378990e1 authored by Abel Tesfaye's avatar Abel Tesfaye
Browse files

Cleanup listener reference in Screen Attention

This will fix a memory leak being caused by dangling listeners.

Test: locally with oriole, make RunSettingsRoboTests -j$(nproc) ROBOTEST_FILTER=AdaptiveSleepCameraStatePreferenceControllerTest,AdaptiveSleepPreferenceControllerTest

Bug: 245990072
Change-Id: I35eeedc3ece719f1f3baff6235cc5ac2d42fbba3
parent 88ea8b3b
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -19,9 +19,15 @@ package com.android.settings.display;
import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
import static android.hardware.SensorPrivacyManager.Sources.DIALOG;

import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;

import android.content.Context;
import android.hardware.SensorPrivacyManager;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.PreferenceScreen;

import com.android.internal.annotations.VisibleForTesting;
@@ -32,17 +38,34 @@ import com.android.settingslib.widget.BannerMessagePreference;
 * The controller of Screen attention's camera disabled warning preference.
 * The preference appears when the camera access is disabled for Screen Attention feature.
 */
public class AdaptiveSleepCameraStatePreferenceController {
public class AdaptiveSleepCameraStatePreferenceController implements LifecycleObserver {
    @VisibleForTesting
    BannerMessagePreference mPreference;
    private final SensorPrivacyManager mPrivacyManager;
    private final Context mContext;

    public AdaptiveSleepCameraStatePreferenceController(Context context) {
    private final SensorPrivacyManager.OnSensorPrivacyChangedListener mPrivacyChangedListener =
            new SensorPrivacyManager.OnSensorPrivacyChangedListener() {
                @Override
                public void onSensorPrivacyChanged(int sensor, boolean enabled) {
                    updateVisibility();
                }
            };

    public AdaptiveSleepCameraStatePreferenceController(Context context, Lifecycle lifecycle) {
        mPrivacyManager = SensorPrivacyManager.getInstance(context);
        mPrivacyManager.addSensorPrivacyListener(CAMERA,
                (sensor, enabled) -> updateVisibility());
        mContext = context;
        lifecycle.addObserver(this);
    }

    @OnLifecycleEvent(ON_START)
    public void onStart() {
        mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener);
    }

    @OnLifecycleEvent(ON_STOP)
    public void onStop() {
        mPrivacyManager.removeSensorPrivacyListener(CAMERA, mPrivacyChangedListener);
    }

    /**
@@ -55,7 +78,7 @@ public class AdaptiveSleepCameraStatePreferenceController {
    }

    /**
     * Need this because all controller tests use RoboElectric. No easy way to mock this service,
     * Need this because all controller tests use Robolectric. No easy way to mock this service,
     * so we mock the call we need
     */
    @VisibleForTesting
+5 −3
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
    };

    private DevicePolicyManager mDevicePolicyManager;
    private SensorPrivacyManager.OnSensorPrivacyChangedListener mPrivacyChangedListener;

    @VisibleForTesting
    Context mContext;
@@ -120,7 +121,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
        mAdaptiveSleepPermissionController = new AdaptiveSleepPermissionPreferenceController(
                context);
        mAdaptiveSleepCameraStatePreferenceController =
                new AdaptiveSleepCameraStatePreferenceController(context);
                new AdaptiveSleepCameraStatePreferenceController(context, getLifecycle());
        mAdaptiveSleepBatterySaverPreferenceController =
                new AdaptiveSleepBatterySaverPreferenceController(context);
        mPrivacyPreference = new FooterPreference(context);
@@ -129,8 +130,7 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
        mPrivacyPreference.setSelectable(false);
        mPrivacyPreference.setLayoutResource(R.layout.preference_footer);
        mPrivacyManager = SensorPrivacyManager.getInstance(context);
        mPrivacyManager.addSensorPrivacyListener(CAMERA,
                (sensor, enabled) -> mAdaptiveSleepController.updatePreference());
        mPrivacyChangedListener = (sensor, enabled) -> mAdaptiveSleepController.updatePreference();
    }

    @Override
@@ -159,12 +159,14 @@ public class ScreenTimeoutSettings extends RadioButtonPickerFragment implements
        mAdaptiveSleepController.updatePreference();
        mContext.registerReceiver(mReceiver,
                new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
        mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener);
    }

    @Override
    public void onStop() {
        super.onStop();
        mContext.unregisterReceiver(mReceiver);
        mPrivacyManager.removeSensorPrivacyListener(CAMERA, mPrivacyChangedListener);
    }

    @Override
+4 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.pm.PackageManager;

import androidx.lifecycle.Lifecycle;
import androidx.preference.PreferenceScreen;

import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
@@ -50,6 +51,8 @@ public class AdaptiveSleepCameraStatePreferenceControllerTest {
    private PackageManager mPackageManager;
    @Mock
    private PreferenceScreen mScreen;
    @Mock
    private Lifecycle mLifecycle;

    @Before
    public void setUp() {
@@ -61,7 +64,7 @@ public class AdaptiveSleepCameraStatePreferenceControllerTest {
        when(mPackageManager.checkPermission(any(), any())).thenReturn(
                PackageManager.PERMISSION_GRANTED);

        mController = new AdaptiveSleepCameraStatePreferenceController(mContext);
        mController = new AdaptiveSleepCameraStatePreferenceController(mContext, mLifecycle);
        when(mController.isCameraLocked()).thenReturn(false);
    }