summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mady Mellor <madym@google.com> 2023-05-12 17:23:51 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-05-12 17:23:51 +0000
commit3af5b5457c974b8493ea859a707393f7eb4123be (patch)
tree5543e2feb0dcad4038eefb78fcc7a23251b16580
parent3c78ba05275b1bbaf99d018deb46c8afd33f60ce (diff)
parent2c4955bcf664e9ed5b9fa5b7fb201c923f9a9b68 (diff)
Merge "Use ComponentCallbacks instead of ConfigurationChangeListener" into udc-dev
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java128
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java65
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java5
3 files changed, 129 insertions, 69 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 3eb9fa2eef6b..698681029595 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -17,12 +17,18 @@
package com.android.wm.shell.bubbles;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
+import static android.content.pm.ActivityInfo.CONFIG_DENSITY;
+import static android.content.pm.ActivityInfo.CONFIG_FONT_SCALE;
+import static android.content.pm.ActivityInfo.CONFIG_LAYOUT_DIRECTION;
+import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED;
import static android.service.notification.NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_GESTURE;
@@ -47,6 +53,7 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
+import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -74,7 +81,6 @@ import android.util.Pair;
import android.util.SparseArray;
import android.view.IWindowManager;
import android.view.SurfaceControl;
-import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowInsets;
@@ -102,6 +108,7 @@ import com.android.wm.shell.common.SingleInstanceRemoteListener;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TaskStackListenerCallback;
import com.android.wm.shell.common.TaskStackListenerImpl;
+import com.android.wm.shell.common.annotations.ExternalMainThread;
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
import com.android.wm.shell.common.annotations.ShellMainThread;
import com.android.wm.shell.common.bubbles.BubbleBarUpdate;
@@ -109,7 +116,6 @@ import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.pip.PinnedStackListenerForwarder;
-import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -135,7 +141,7 @@ import java.util.function.IntConsumer;
*
* The controller manages addition, removal, and visible state of bubbles on screen.
*/
-public class BubbleController implements ConfigurationChangeListener,
+public class BubbleController implements ComponentCallbacks2,
RemoteCallable<BubbleController> {
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
@@ -153,7 +159,6 @@ public class BubbleController implements ConfigurationChangeListener,
private static final boolean BUBBLE_BAR_ENABLED =
SystemProperties.getBoolean("persist.wm.debug.bubble_bar", false);
-
/**
* Common interface to send updates to bubble views.
*/
@@ -237,17 +242,17 @@ public class BubbleController implements ConfigurationChangeListener,
/** Whether or not the BubbleStackView has been added to the WindowManager. */
private boolean mAddedToWindowManager = false;
- /** Saved screen density, used to detect display size changes in {@link #onConfigChanged}. */
- private int mDensityDpi = Configuration.DENSITY_DPI_UNDEFINED;
-
- /** Saved screen bounds, used to detect screen size changes in {@link #onConfigChanged}. **/
- private Rect mScreenBounds = new Rect();
-
- /** Saved font scale, used to detect font size changes in {@link #onConfigChanged}. */
- private float mFontScale = 0;
+ /**
+ * Saved configuration, used to detect changes in
+ * {@link #onConfigurationChanged(Configuration)}
+ */
+ private final Configuration mLastConfiguration = new Configuration();
- /** Saved direction, used to detect layout direction changes @link #onConfigChanged}. */
- private int mLayoutDirection = View.LAYOUT_DIRECTION_UNDEFINED;
+ /**
+ * Saved screen bounds, used to detect screen size changes in
+ * {@link #onConfigurationChanged(Configuration)}.
+ */
+ private final Rect mScreenBounds = new Rect();
/** Saved insets, used to detect WindowInset changes. */
private WindowInsets mWindowInsets;
@@ -293,7 +298,8 @@ public class BubbleController implements ConfigurationChangeListener,
TaskViewTransitions taskViewTransitions,
SyncTransactionQueue syncQueue,
IWindowManager wmService) {
- mContext = context;
+ mContext = context.createWindowContext(TYPE_APPLICATION_OVERLAY, null);
+ mLastConfiguration.setTo(mContext.getResources().getConfiguration());
mShellCommandHandler = shellCommandHandler;
mShellController = shellController;
mLauncherApps = launcherApps;
@@ -317,11 +323,11 @@ public class BubbleController implements ConfigurationChangeListener,
mBubblePositioner = positioner;
mBubbleData = data;
mSavedUserBubbleData = new SparseArray<>();
- mBubbleIconFactory = new BubbleIconFactory(context,
- context.getResources().getDimensionPixelSize(R.dimen.bubble_size),
- context.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
- context.getResources().getColor(R.color.important_conversation),
- context.getResources().getDimensionPixelSize(
+ mBubbleIconFactory = new BubbleIconFactory(mContext,
+ mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size),
+ mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
+ mContext.getResources().getColor(R.color.important_conversation),
+ mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.importance_ring_stroke_width));
mDisplayController = displayController;
mTaskViewTransitions = taskViewTransitions;
@@ -482,7 +488,6 @@ public class BubbleController implements ConfigurationChangeListener,
}
mCurrentProfiles = userProfiles;
- mShellController.addConfigurationChangeListener(this);
mShellController.addExternalInterface(KEY_EXTRA_SHELL_BUBBLES,
this::createExternalInterface, this);
mShellCommandHandler.addDumpCallback(this::dump, this);
@@ -774,6 +779,7 @@ public class BubbleController implements ConfigurationChangeListener,
try {
mAddedToWindowManager = true;
registerBroadcastReceiver();
+ mContext.registerComponentCallbacks(this);
mBubbleData.getOverflow().initialize(this);
// (TODO: b/273314541) some duplication in the inset listener
if (isShowingAsBubbleBar()) {
@@ -831,6 +837,7 @@ public class BubbleController implements ConfigurationChangeListener,
// Put on background for this binder call, was causing jank
mBackgroundExecutor.execute(() -> {
try {
+ mContext.unregisterComponentCallbacks(this);
mContext.unregisterReceiver(mBroadcastReceiver);
} catch (IllegalArgumentException e) {
// Not sure if this happens in production, but was happening in tests
@@ -930,8 +937,7 @@ public class BubbleController implements ConfigurationChangeListener,
mSavedUserBubbleData.remove(userId);
}
- @Override
- public void onThemeChanged() {
+ private void onThemeChanged() {
if (mStackView != null) {
mStackView.onThemeChanged();
}
@@ -963,34 +969,60 @@ public class BubbleController implements ConfigurationChangeListener,
}
}
+ // Note: Component callbacks are always called on the main thread of the process
+ @ExternalMainThread
@Override
public void onConfigurationChanged(Configuration newConfig) {
- if (mBubblePositioner != null) {
- mBubblePositioner.update();
- }
- if (mStackView != null && newConfig != null) {
- if (newConfig.densityDpi != mDensityDpi
- || !newConfig.windowConfiguration.getBounds().equals(mScreenBounds)) {
- mDensityDpi = newConfig.densityDpi;
- mScreenBounds.set(newConfig.windowConfiguration.getBounds());
- mBubbleData.onMaxBubblesChanged();
- mBubbleIconFactory = new BubbleIconFactory(mContext,
- mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size),
- mContext.getResources().getDimensionPixelSize(R.dimen.bubble_badge_size),
- mContext.getResources().getColor(R.color.important_conversation),
- mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.importance_ring_stroke_width));
- mStackView.onDisplaySizeChanged();
- }
- if (newConfig.fontScale != mFontScale) {
- mFontScale = newConfig.fontScale;
- mStackView.updateFontScale();
- }
- if (newConfig.getLayoutDirection() != mLayoutDirection) {
- mLayoutDirection = newConfig.getLayoutDirection();
- mStackView.onLayoutDirectionChanged(mLayoutDirection);
+ mMainExecutor.execute(() -> {
+ final int diff = newConfig.diff(mLastConfiguration);
+ final boolean themeChanged = (diff & CONFIG_ASSETS_PATHS) != 0
+ || (diff & CONFIG_UI_MODE) != 0;
+ if (themeChanged) {
+ onThemeChanged();
}
- }
+ if (mBubblePositioner != null) {
+ mBubblePositioner.update();
+ }
+ if (mStackView != null) {
+ final boolean densityChanged = (diff & CONFIG_DENSITY) != 0;
+ final boolean fontScaleChanged = (diff & CONFIG_FONT_SCALE) != 0;
+ final boolean layoutDirectionChanged = (diff & CONFIG_LAYOUT_DIRECTION) != 0;
+ if (densityChanged
+ || !newConfig.windowConfiguration.getBounds().equals(mScreenBounds)) {
+ mScreenBounds.set(newConfig.windowConfiguration.getBounds());
+ mBubbleData.onMaxBubblesChanged();
+ mBubbleIconFactory = new BubbleIconFactory(mContext,
+ mContext.getResources().getDimensionPixelSize(R.dimen.bubble_size),
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.bubble_badge_size),
+ mContext.getResources().getColor(R.color.important_conversation),
+ mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.importance_ring_stroke_width));
+ mStackView.onDisplaySizeChanged();
+ }
+ if (fontScaleChanged) {
+ mStackView.updateFontScale();
+ }
+ if (layoutDirectionChanged) {
+ mStackView.onLayoutDirectionChanged(newConfig.getLayoutDirection());
+ }
+ }
+ mLastConfiguration.setTo(newConfig);
+ });
+ }
+
+ // Note: Component callbacks are always called on the main thread of the process
+ @ExternalMainThread
+ @Override
+ public void onTrimMemory(int level) {
+ // Do nothing
+ }
+
+ // Note: Component callbacks are always called on the main thread of the process
+ @ExternalMainThread
+ @Override
+ public void onLowMemory() {
+ // Do nothing
}
private void onNotificationPanelExpandedChanged(boolean expanded) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 47a86b1fca5c..f0683a4628b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -300,6 +300,10 @@ public class BubblesTest extends SysuiTestCase {
private UserHandle mUser0;
+ // The window context being used by the controller, use this to verify
+ // any actions on the context.
+ private Context mBubbleControllerContext;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -436,6 +440,8 @@ public class BubblesTest extends SysuiTestCase {
// Get a reference to KeyguardStateController.Callback
verify(mKeyguardStateController, atLeastOnce())
.addCallback(mKeyguardStateControllerCallbackCaptor.capture());
+
+ mBubbleControllerContext = mBubbleController.getContext();
}
@After
@@ -468,11 +474,6 @@ public class BubblesTest extends SysuiTestCase {
}
@Test
- public void instantiateController_registerConfigChangeListener() {
- verify(mShellController, times(1)).addConfigurationChangeListener(any());
- }
-
- @Test
public void testAddBubble() {
mBubbleController.updateBubble(mBubbleEntry);
assertTrue(mBubbleController.hasBubbles());
@@ -1385,13 +1386,28 @@ public class BubblesTest extends SysuiTestCase {
assertStackCollapsed();
}
+ @Test
+ public void testRegisterUnregisterComponentCallbacks() {
+ spyOn(mBubbleControllerContext);
+ mBubbleController.updateBubble(mBubbleEntry);
+ verify(mBubbleControllerContext).registerComponentCallbacks(eq(mBubbleController));
+
+ mBubbleData.dismissBubbleWithKey(mBubbleEntry.getKey(), REASON_APP_CANCEL);
+ // TODO: not certain why this isn't called normally when tests are run, perhaps because
+ // it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe
+ mBubbleController.onAllBubblesAnimatedOut();
+
+ verify(mBubbleControllerContext).unregisterComponentCallbacks(eq(mBubbleController));
+ }
@Test
public void testRegisterUnregisterBroadcastListener() {
- spyOn(mContext);
+ spyOn(mBubbleControllerContext);
mBubbleController.updateBubble(mBubbleEntry);
- verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
- mFilterArgumentCaptor.capture(), eq(Context.RECEIVER_EXPORTED));
+ verify(mBubbleControllerContext).registerReceiver(
+ mBroadcastReceiverArgumentCaptor.capture(),
+ mFilterArgumentCaptor.capture(),
+ eq(Context.RECEIVER_EXPORTED));
assertThat(mFilterArgumentCaptor.getValue()
.hasAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)).isTrue();
assertThat(mFilterArgumentCaptor.getValue()
@@ -1402,47 +1418,54 @@ public class BubblesTest extends SysuiTestCase {
// it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe
mBubbleController.onAllBubblesAnimatedOut();
- verify(mContext).unregisterReceiver(eq(mBroadcastReceiverArgumentCaptor.getValue()));
+ verify(mBubbleControllerContext).unregisterReceiver(
+ eq(mBroadcastReceiverArgumentCaptor.getValue()));
}
@Test
public void testBroadcastReceiverCloseDialogs_notGestureNav() {
- spyOn(mContext);
+ spyOn(mBubbleControllerContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
- verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
- mFilterArgumentCaptor.capture(), eq(Context.RECEIVER_EXPORTED));
+ verify(mBubbleControllerContext).registerReceiver(
+ mBroadcastReceiverArgumentCaptor.capture(),
+ mFilterArgumentCaptor.capture(),
+ eq(Context.RECEIVER_EXPORTED));
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mBubbleControllerContext, i);
assertStackExpanded();
}
@Test
public void testBroadcastReceiverCloseDialogs_reasonGestureNav() {
- spyOn(mContext);
+ spyOn(mBubbleControllerContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
- verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
- mFilterArgumentCaptor.capture(), eq(Context.RECEIVER_EXPORTED));
+ verify(mBubbleControllerContext).registerReceiver(
+ mBroadcastReceiverArgumentCaptor.capture(),
+ mFilterArgumentCaptor.capture(),
+ eq(Context.RECEIVER_EXPORTED));
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
i.putExtra("reason", "gestureNav");
- mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mBubbleControllerContext, i);
assertStackCollapsed();
}
@Test
public void testBroadcastReceiver_screenOff() {
- spyOn(mContext);
+ spyOn(mBubbleControllerContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
- verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
- mFilterArgumentCaptor.capture(), eq(Context.RECEIVER_EXPORTED));
+ verify(mBubbleControllerContext).registerReceiver(
+ mBroadcastReceiverArgumentCaptor.capture(),
+ mFilterArgumentCaptor.capture(),
+ eq(Context.RECEIVER_EXPORTED));
Intent i = new Intent(Intent.ACTION_SCREEN_OFF);
- mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+ mBroadcastReceiverArgumentCaptor.getValue().onReceive(mBubbleControllerContext, i);
assertStackCollapsed();
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
index 5ff57aad9f5d..4b6dd3ef9d62 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
@@ -19,6 +19,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.display.DisplayManager;
+import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.testing.LeakCheck;
@@ -62,6 +63,10 @@ public class SysuiTestableContext extends TestableContext {
return (SysuiTestableContext) createDisplayContext(display);
}
+ public SysuiTestableContext createWindowContext(int type, Bundle bundle) {
+ return new SysuiTestableContext(getBaseContext().createWindowContext(type, bundle));
+ }
+
public void cleanUpReceivers(String testName) {
Set<BroadcastReceiver> copy;
synchronized (mRegisteredReceivers) {