From aca97636d2591723862825223a2b5ddcccf462e4 Mon Sep 17 00:00:00 2001 From: lpeter Date: Tue, 11 Jun 2019 11:13:54 +0800 Subject: [PATCH] Fix SysUI / AoD leaking content observers It will add one more setting observer when AOD state is changed from DOZE_PULSING to DOZE/DOZE_AOD. Avoid to register setting observer again when it has been registered before. For example: This issue will occur when receving notification in AOD. Bug: 133388082 Test: atest SystemUITests Change-Id: Ie3fccc4dd6ecc77692649ace401779b8398b63f8 --- .../android/systemui/doze/DozeSensors.java | 21 ++++++++++------ .../systemui/doze/DozeSensorsTest.java | 24 +++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java index 831d07446e7cb..5f52486b2bc63 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java @@ -70,11 +70,12 @@ public class DozeSensors { private final Consumer mProxCallback; private final Callback mCallback; @VisibleForTesting - protected final TriggerSensor[] mSensors; + protected TriggerSensor[] mSensors; private final Handler mHandler = new Handler(); private final ProxSensor mProxSensor; private long mDebounceFrom; + private boolean mSettingRegistered; public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager, DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock, @@ -172,13 +173,8 @@ public class DozeSensors { public void setListening(boolean listen) { for (TriggerSensor s : mSensors) { s.setListening(listen); - if (listen) { - s.registerSettingsObserver(mSettingsObserver); - } - } - if (!listen) { - mResolver.unregisterContentObserver(mSettingsObserver); } + registerSettingsObserverIfNeeded(listen); } /** Set the listening state of only the sensors that require the touchscreen. */ @@ -240,6 +236,17 @@ public class DozeSensors { return mProxSensor.mCurrentlyFar; } + private void registerSettingsObserverIfNeeded(boolean register) { + if (!register) { + mResolver.unregisterContentObserver(mSettingsObserver); + } else if (!mSettingRegistered) { + for (TriggerSensor s : mSensors) { + s.registerSettingsObserver(mSettingsObserver); + } + } + mSettingRegistered = register; + } + private class ProxSensor implements SensorEventListener { boolean mRequested; diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java index 4467faf66830a..33042918cfc90 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java @@ -27,10 +27,12 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AlarmManager; +import android.database.ContentObserver; import android.hardware.display.AmbientDisplayConfiguration; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -39,6 +41,7 @@ import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import com.android.systemui.doze.DozeSensors.TriggerSensor; import com.android.systemui.plugins.SensorManagerPlugin; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.util.AsyncSensorManager; @@ -73,6 +76,8 @@ public class DozeSensorsTest extends SysuiTestCase { private Consumer mProxCallback; @Mock private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy; + @Mock + private TriggerSensor mMockTriggerSensor; private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener; private TestableLooper mTestableLooper; private DozeSensors mDozeSensors; @@ -107,6 +112,25 @@ public class DozeSensorsTest extends SysuiTestCase { anyBoolean(), anyFloat(), anyFloat(), eq(null)); } + @Test + public void testSetListening_firstTrue_registerSettingsObserver() { + mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor}; + + mDozeSensors.setListening(true); + + verify(mMockTriggerSensor).registerSettingsObserver(any(ContentObserver.class)); + } + + @Test + public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() { + mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor}; + mDozeSensors.setListening(true); + + mDozeSensors.setListening(true); + + verify(mMockTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class)); + } + private class TestableDozeSensors extends DozeSensors { TestableDozeSensors() {