diff options
| author | 2023-12-08 16:10:03 +0100 | |
|---|---|---|
| committer | 2023-12-08 16:54:22 +0000 | |
| commit | 901ec9410363f816c2045bc17a9a6c9d9c7ae579 (patch) | |
| tree | ac4d15b8c25eee1f38ae60096daea7a0585a76d2 | |
| parent | 9735d938433dff3b322b856cb5095f9d770d7d7a (diff) | |
Fix BroadcastReceiver registration in DefaultDeviceEffectsApplier
Test: atest DefaultDeviceEffectsApplierTest
Bug: 308673343
Change-Id: I0dc733b4846876af4c27737ef6285d8e4ab4597e
2 files changed, 27 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java index 82faeefa9350..885566693b9a 100644 --- a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java +++ b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java @@ -32,6 +32,8 @@ import android.service.notification.ZenDeviceEffects; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ConfigChangeOrigin; +import com.android.internal.annotations.GuardedBy; + /** Default implementation for {@link DeviceEffectsApplier}. */ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { @@ -50,6 +52,10 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { private final UiModeManager mUiModeManager; private final WallpaperManager mWallpaperManager; + private final Object mRegisterReceiverLock = new Object(); + @GuardedBy("mRegisterReceiverLock") + private boolean mIsScreenOffReceiverRegistered; + private ZenDeviceEffects mLastAppliedEffects = new ZenDeviceEffects.Builder().build(); private boolean mPendingNightMode; @@ -96,7 +102,6 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { private void updateOrScheduleNightMode(boolean useNightMode, @ConfigChangeOrigin int origin) { mPendingNightMode = useNightMode; - safeUnregisterReceiver(mNightModeWhenScreenOff); // Changing the theme can be disruptive for the user (Activities are likely recreated, may // lose some state). Therefore we only apply the change immediately if the rule was @@ -106,17 +111,18 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { || origin == ZenModeConfig.UPDATE_ORIGIN_USER || origin == ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI || !mPowerManager.isInteractive()) { + unregisterScreenOffReceiver(); updateNightModeImmediately(useNightMode); } else { - mContext.registerReceiver(mNightModeWhenScreenOff, SCREEN_OFF_INTENT_FILTER, - Context.RECEIVER_NOT_EXPORTED); + registerScreenOffReceiver(); } } + @GuardedBy("mRegisterReceiverLock") private final BroadcastReceiver mNightModeWhenScreenOff = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - safeUnregisterReceiver(mNightModeWhenScreenOff); + unregisterScreenOffReceiver(); updateNightModeImmediately(mPendingNightMode); } }; @@ -130,11 +136,22 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { }); } - private void safeUnregisterReceiver(BroadcastReceiver br) { - try { - mContext.unregisterReceiver(br); - } catch (IllegalArgumentException e) { - // It's fine, we haven't registered it yet. + private void registerScreenOffReceiver() { + synchronized (mRegisterReceiverLock) { + if (!mIsScreenOffReceiverRegistered) { + mContext.registerReceiver(mNightModeWhenScreenOff, SCREEN_OFF_INTENT_FILTER, + Context.RECEIVER_NOT_EXPORTED); + mIsScreenOffReceiverRegistered = true; + } + } + } + + private void unregisterScreenOffReceiver() { + synchronized (mRegisterReceiverLock) { + if (mIsScreenOffReceiverRegistered) { + mIsScreenOffReceiverRegistered = false; + mContext.unregisterReceiver(mNightModeWhenScreenOff); + } } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java index c9e6d6a61a38..8936dc61e6ef 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java @@ -27,7 +27,6 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -200,7 +199,7 @@ public class DefaultDeviceEffectsApplierTest { // So the effect is applied, and we stopped listening for this event. verify(mUiModeManager).setNightModeActivatedForCustomMode( eq(MODE_NIGHT_CUSTOM_TYPE_BEDTIME), eq(true)); - verify(mContext, atLeastOnce()).unregisterReceiver(eq(screenOffReceiver)); + verify(mContext).unregisterReceiver(eq(screenOffReceiver)); } @Test |