From febccc4990117b26f8afede08e5ef0e3806f8885 Mon Sep 17 00:00:00 2001 From: Abel Tesfaye Date: Thu, 1 Sep 2022 02:35:07 +0000 Subject: [PATCH] Cleanup listener reference in SmartAutoRotate This will fix a memory leak caused by dangling SensorPrivacy listeners. Test: opened/closed display and auto-rotate fragment and verified no leaks in android studio profiler Bug: 244382423 Change-Id: Ie2d070e796fa473e8f2794c9934c62edc4f7092c --- ...SmartAutoRotateBatterySaverController.java | 14 ++++---- .../SmartAutoRotateCameraStateController.java | 36 +++++++++++++++---- .../display/SmartAutoRotateController.java | 13 +++++-- .../SmartAutoRotatePreferenceController.java | 26 +++++++++----- 4 files changed, 66 insertions(+), 23 deletions(-) diff --git a/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java b/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java index 9d4645e1fd0..8400cbb2467 100644 --- a/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java +++ b/src/com/android/settings/display/SmartAutoRotateBatterySaverController.java @@ -16,6 +16,9 @@ package com.android.settings.display; +import static androidx.lifecycle.Lifecycle.Event.ON_START; +import static androidx.lifecycle.Lifecycle.Event.ON_STOP; + import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable; import android.content.BroadcastReceiver; @@ -25,14 +28,13 @@ import android.content.IntentFilter; import android.os.PowerManager; import androidx.annotation.VisibleForTesting; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnStart; -import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.widget.BannerMessagePreference; /** @@ -40,7 +42,7 @@ import com.android.settingslib.widget.BannerMessagePreference; * when battery saver mode is enabled. */ public class SmartAutoRotateBatterySaverController extends BasePreferenceController implements - LifecycleObserver, OnStart, OnStop { + LifecycleObserver { private Preference mPreference; private final PowerManager mPowerManager; @@ -76,13 +78,13 @@ public class SmartAutoRotateBatterySaverController extends BasePreferenceControl }); } - @Override + @OnLifecycleEvent(ON_START) public void onStart() { mContext.registerReceiver(mReceiver, new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)); } - @Override + @OnLifecycleEvent(ON_STOP) public void onStop() { mContext.unregisterReceiver(mReceiver); } diff --git a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java index d761edc9e3e..56acbe19ab7 100644 --- a/src/com/android/settings/display/SmartAutoRotateCameraStateController.java +++ b/src/com/android/settings/display/SmartAutoRotateCameraStateController.java @@ -19,11 +19,16 @@ 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 static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable; import android.content.Context; import android.hardware.SensorPrivacyManager; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -36,20 +41,37 @@ import com.android.settingslib.widget.BannerMessagePreference; * The controller of camera based rotate privacy sensor warning preference. The preference appears * when the privacy sensor service disables camera functionality completely. */ -public class SmartAutoRotateCameraStateController extends BasePreferenceController { +public class SmartAutoRotateCameraStateController extends BasePreferenceController implements + LifecycleObserver { private final SensorPrivacyManager mPrivacyManager; private Preference mPreference; + private final SensorPrivacyManager.OnSensorPrivacyChangedListener mPrivacyChangedListener = + new SensorPrivacyManager.OnSensorPrivacyChangedListener() { + @Override + public void onSensorPrivacyChanged(int sensor, boolean enabled) { + if (mPreference != null) { + mPreference.setVisible(isAvailable()); + } + updateState(mPreference); + } + }; + public SmartAutoRotateCameraStateController(Context context, String key) { super(context, key); mPrivacyManager = SensorPrivacyManager.getInstance(context); - mPrivacyManager.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> { - if (mPreference != null) { - mPreference.setVisible(isAvailable()); - } - updateState(mPreference); - }); + } + + @OnLifecycleEvent(ON_START) + public void onStart() { + mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener); + + } + + @OnLifecycleEvent(ON_STOP) + public void onStop() { + mPrivacyManager.removeSensorPrivacyListener(CAMERA, mPrivacyChangedListener); } @VisibleForTesting diff --git a/src/com/android/settings/display/SmartAutoRotateController.java b/src/com/android/settings/display/SmartAutoRotateController.java index 093c8459cd5..9740002823d 100644 --- a/src/com/android/settings/display/SmartAutoRotateController.java +++ b/src/com/android/settings/display/SmartAutoRotateController.java @@ -65,6 +65,15 @@ public class SmartAutoRotateController extends TogglePreferenceController implem updateState(mPreference); } }; + + private final SensorPrivacyManager.OnSensorPrivacyChangedListener mPrivacyChangedListener = + new SensorPrivacyManager.OnSensorPrivacyChangedListener() { + @Override + public void onSensorPrivacyChanged(int sensor, boolean enabled) { + updateState(mPreference); + } + }; + private final DeviceStateRotationLockSettingsManager mDeviceStateAutoRotateSettingsManager; private final DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener mDeviceStateRotationLockSettingsListener = () -> updateState(mPreference); @@ -74,8 +83,6 @@ public class SmartAutoRotateController extends TogglePreferenceController implem super(context, preferenceKey); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mPrivacyManager = SensorPrivacyManager.getInstance(context); - mPrivacyManager - .addSensorPrivacyListener(CAMERA, (sensor, enabled) -> updateState(mPreference)); mPowerManager = context.getSystemService(PowerManager.class); mDeviceStateAutoRotateSettingsManager = DeviceStateRotationLockSettingsManager.getInstance( context); @@ -134,6 +141,7 @@ public class SmartAutoRotateController extends TogglePreferenceController implem RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener); mDeviceStateAutoRotateSettingsManager.registerListener( mDeviceStateRotationLockSettingsListener); + mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener); } @OnLifecycleEvent(ON_STOP) @@ -145,6 +153,7 @@ public class SmartAutoRotateController extends TogglePreferenceController implem } mDeviceStateAutoRotateSettingsManager.unregisterListener( mDeviceStateRotationLockSettingsListener); + mPrivacyManager.removeSensorPrivacyListener(CAMERA, mPrivacyChangedListener); } @Override diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java index abf4f0c4b12..73f81eb7692 100644 --- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java +++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java @@ -19,6 +19,9 @@ package com.android.settings.display; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.provider.Settings.Secure.CAMERA_AUTOROTATE; +import static androidx.lifecycle.Lifecycle.Event.ON_START; +import static androidx.lifecycle.Lifecycle.Event.ON_STOP; + import static com.android.settings.display.SmartAutoRotateController.hasSufficientPermission; import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable; @@ -33,6 +36,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.OnLifecycleEvent; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -42,15 +47,12 @@ import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnStart; -import com.android.settingslib.core.lifecycle.events.OnStop; /** * SmartAutoRotatePreferenceController provides auto rotate summary in display settings */ public class SmartAutoRotatePreferenceController extends TogglePreferenceController - implements LifecycleObserver, OnStart, OnStop { + implements LifecycleObserver { private final MetricsFeatureProvider mMetricsFeatureProvider; private final SensorPrivacyManager mPrivacyManager; @@ -62,14 +64,20 @@ public class SmartAutoRotatePreferenceController extends TogglePreferenceControl } }; + private final SensorPrivacyManager.OnSensorPrivacyChangedListener mPrivacyChangedListener = + new SensorPrivacyManager.OnSensorPrivacyChangedListener() { + @Override + public void onSensorPrivacyChanged(int sensor, boolean enabled) { + refreshSummary(mPreference); + } + }; + private RotationPolicy.RotationPolicyListener mRotationPolicyListener; private Preference mPreference; public SmartAutoRotatePreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); mPrivacyManager = SensorPrivacyManager.getInstance(context); - mPrivacyManager - .addSensorPrivacyListener(CAMERA, (sensor, enabled) -> refreshSummary(mPreference)); mPowerManager = context.getSystemService(PowerManager.class); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); } @@ -108,7 +116,7 @@ public class SmartAutoRotatePreferenceController extends TogglePreferenceControl refreshSummary(mPreference); } - @Override + @OnLifecycleEvent(ON_START) public void onStart() { mContext.registerReceiver(mReceiver, new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)); @@ -124,15 +132,17 @@ public class SmartAutoRotatePreferenceController extends TogglePreferenceControl } RotationPolicy.registerRotationPolicyListener(mContext, mRotationPolicyListener); + mPrivacyManager.addSensorPrivacyListener(CAMERA, mPrivacyChangedListener); } - @Override + @OnLifecycleEvent(ON_STOP) public void onStop() { mContext.unregisterReceiver(mReceiver); if (mRotationPolicyListener != null) { RotationPolicy.unregisterRotationPolicyListener(mContext, mRotationPolicyListener); } + mPrivacyManager.removeSensorPrivacyListener(CAMERA, mPrivacyChangedListener); } /**