summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java107
4 files changed, 138 insertions, 11 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 12b6e1b6bea5..09be41b56a10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -114,6 +114,13 @@ public interface NotificationsModule {
@Binds
NotifGutsViewManager bindNotifGutsViewManager(NotificationGutsManager notificationGutsManager);
+ /** Binds {@link NotificationGutsManager} as a {@link CoreStartable}. */
+ @Binds
+ @IntoMap
+ @ClassKey(NotificationGutsManager.class)
+ CoreStartable bindsNotificationGutsManager(NotificationGutsManager notificationGutsManager);
+
+
/** Provides an instance of {@link VisibilityLocationProvider} */
@Binds
VisibilityLocationProvider bindVisibilityLocationProvider(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 6f79ea8c543b..44ead26de012 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -45,6 +45,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.notification.ConversationIconFactory;
+import com.android.systemui.CoreStartable;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
@@ -53,6 +54,7 @@ import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -69,6 +71,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.wmshell.BubblesManager;
import java.util.Optional;
@@ -80,7 +83,7 @@ import javax.inject.Inject;
* closing guts, and keeping track of the currently exposed notification guts.
*/
@SysUISingleton
-public class NotificationGutsManager implements NotifGutsViewManager {
+public class NotificationGutsManager implements NotifGutsViewManager, CoreStartable {
private static final String TAG = "NotificationGutsManager";
// Must match constant in Settings. Used to highlight preferences when linking to Settings.
@@ -109,6 +112,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
private final Handler mMainHandler;
private final Handler mBgHandler;
+ private final JavaAdapter mJavaAdapter;
private final Optional<BubblesManager> mBubblesManagerOptional;
private Runnable mOpenRunnable;
private final INotificationManager mNotificationManager;
@@ -121,6 +125,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
private final UserContextProvider mContextTracker;
private final UiEventLogger mUiEventLogger;
private final ShadeController mShadeController;
+ private final WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
private NotifGutsViewListener mGutsListener;
private final HeadsUpManagerPhone mHeadsUpManagerPhone;
private final ActivityStarter mActivityStarter;
@@ -129,6 +134,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
public NotificationGutsManager(Context context,
@Main Handler mainHandler,
@Background Handler bgHandler,
+ JavaAdapter javaAdapter,
AccessibilityManager accessibilityManager,
HighPriorityProvider highPriorityProvider,
INotificationManager notificationManager,
@@ -143,6 +149,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
UiEventLogger uiEventLogger,
OnUserInteractionCallback onUserInteractionCallback,
ShadeController shadeController,
+ WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
NotificationLockscreenUserManager notificationLockscreenUserManager,
StatusBarStateController statusBarStateController,
DeviceProvisionedController deviceProvisionedController,
@@ -152,6 +159,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
mContext = context;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
+ mJavaAdapter = javaAdapter;
mAccessibilityManager = accessibilityManager;
mHighPriorityProvider = highPriorityProvider;
mNotificationManager = notificationManager;
@@ -166,6 +174,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
mUiEventLogger = uiEventLogger;
mOnUserInteractionCallback = onUserInteractionCallback;
mShadeController = shadeController;
+ mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
mLockscreenUserManager = notificationLockscreenUserManager;
mStatusBarStateController = statusBarStateController;
mDeviceProvisionedController = deviceProvisionedController;
@@ -187,6 +196,25 @@ public class NotificationGutsManager implements NotifGutsViewManager {
mNotificationActivityStarter = notificationActivityStarter;
}
+ @Override
+ public void start() {
+ mJavaAdapter.alwaysCollectFlow(
+ mWindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible(),
+ this::onLockscreenShadeVisibilityChanged);
+ }
+
+ private void onLockscreenShadeVisibilityChanged(boolean visible) {
+ if (!visible) {
+ closeAndSaveGuts(
+ /* removeLeavebehind= */ true ,
+ /* force= */ true,
+ /* removeControls= */ true,
+ /* x= */ -1,
+ /* y= */ -1,
+ /* resetMenu= */ true);
+ }
+ }
+
public void onDensityOrFontScaleChanged(NotificationEntry entry) {
setExposedGuts(entry.getGuts());
bindGuts(entry.getRow());
@@ -512,7 +540,7 @@ public class NotificationGutsManager implements NotifGutsViewManager {
mNotificationGutsExposed.removeCallbacks(mOpenRunnable);
mNotificationGutsExposed.closeControls(removeLeavebehinds, removeControls, x, y, force);
}
- if (resetMenu) {
+ if (resetMenu && mListContainer != null) {
mListContainer.resetExposedMenuView(false /* animate */, true /* force */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 711dae667d76..381c9bbfcd84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -3201,9 +3201,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
if (visible) {
DejankUtils.notifyRendererOfExpensiveFrame(
getNotificationShadeWindowView(), "onShadeVisibilityChanged");
- } else {
- mGutsManager.closeAndSaveGuts(true /* removeLeavebehind */, true /* force */,
- true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 705d52bcf13f..9e0f83c9fc53 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -37,6 +37,7 @@ import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -66,11 +67,16 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.keyguard.TestScopeProvider;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository;
+import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -84,6 +90,9 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager.O
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.kotlin.JavaAdapter;
+import com.android.systemui.util.time.FakeSystemClock;
import com.android.systemui.wmshell.BubblesManager;
import org.junit.Before;
@@ -97,6 +106,8 @@ import org.mockito.junit.MockitoRule;
import java.util.Optional;
+import kotlinx.coroutines.test.TestScope;
+
/**
* Tests for {@link NotificationGutsManager}.
*/
@@ -108,6 +119,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+
+ private TestScope mTestScope = TestScopeProvider.getTestScope();
+ private JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope());
+ private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private TestableLooper mTestableLooper;
private Handler mHandler;
private NotificationTestHelper mHelper;
@@ -124,6 +139,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private AccessibilityManager mAccessibilityManager;
@Mock private HighPriorityProvider mHighPriorityProvider;
@Mock private INotificationManager mINotificationManager;
+ @Mock private IStatusBarService mBarService;
@Mock private LauncherApps mLauncherApps;
@Mock private ShortcutManager mShortcutManager;
@Mock private ChannelEditorDialogController mChannelEditorDialogController;
@@ -140,6 +156,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private UserManager mUserManager;
+ private WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
+
@Before
public void setUp() {
mTestableLooper = TestableLooper.get(this);
@@ -148,21 +166,42 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
- mGutsManager = new NotificationGutsManager(mContext, mHandler, mHandler,
+ mWindowRootViewVisibilityInteractor = new WindowRootViewVisibilityInteractor(
+ mTestScope.getBackgroundScope(),
+ new WindowRootViewVisibilityRepository(mBarService, mExecutor),
+ new FakeKeyguardRepository(),
+ mHeadsUpManagerPhone);
+
+ mGutsManager = new NotificationGutsManager(
+ mContext,
+ mHandler,
+ mHandler,
+ mJavaAdapter,
mAccessibilityManager,
- mHighPriorityProvider, mINotificationManager, mUserManager,
- mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
- mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
- Optional.of(mBubblesManager), new UiEventLoggerFake(), mOnUserInteractionCallback,
+ mHighPriorityProvider,
+ mINotificationManager,
+ mUserManager,
+ mPeopleSpaceWidgetManager,
+ mLauncherApps,
+ mShortcutManager,
+ mChannelEditorDialogController,
+ mContextTracker,
+ mAssistantFeedbackController,
+ Optional.of(mBubblesManager),
+ new UiEventLoggerFake(),
+ mOnUserInteractionCallback,
mShadeController,
+ mWindowRootViewVisibilityInteractor,
mNotificationLockscreenUserManager,
mStatusBarStateController,
mDeviceProvisionedController,
mMetricsLogger,
- mHeadsUpManagerPhone, mActivityStarter);
+ mHeadsUpManagerPhone,
+ mActivityStarter);
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
+ mGutsManager.start();
}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -210,6 +249,62 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
}
@Test
+ public void testLockscreenShadeVisible_visible_gutsNotClosed() {
+ // First, start out lockscreen or shade as not visible
+ mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false);
+ mTestScope.getTestScheduler().runCurrent();
+
+ NotificationGuts guts = mock(NotificationGuts.class);
+ mGutsManager.setExposedGuts(guts);
+
+ // WHEN the lockscreen or shade becomes visible
+ mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
+ mTestScope.getTestScheduler().runCurrent();
+
+ // THEN the guts are not closed
+ verify(guts, never()).removeCallbacks(any());
+ verify(guts, never()).closeControls(
+ anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean());
+ }
+
+ @Test
+ public void testLockscreenShadeVisible_notVisible_gutsClosed() {
+ // First, start out lockscreen or shade as visible
+ mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
+ mTestScope.getTestScheduler().runCurrent();
+
+ NotificationGuts guts = mock(NotificationGuts.class);
+ mGutsManager.setExposedGuts(guts);
+
+ // WHEN the lockscreen or shade is no longer visible
+ mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false);
+ mTestScope.getTestScheduler().runCurrent();
+
+ // THEN the guts are closed
+ verify(guts).removeCallbacks(any());
+ verify(guts).closeControls(
+ /* leavebehinds= */ eq(true),
+ /* controls= */ eq(true),
+ /* x= */ anyInt(),
+ /* y= */ anyInt(),
+ /* force= */ eq(true));
+ }
+
+ @Test
+ public void testLockscreenShadeVisible_notVisible_listContainerReset() {
+ // First, start out lockscreen or shade as visible
+ mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(true);
+ mTestScope.getTestScheduler().runCurrent();
+
+ // WHEN the lockscreen or shade is no longer visible
+ mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(false);
+ mTestScope.getTestScheduler().runCurrent();
+
+ // THEN the list container is reset
+ verify(mNotificationListContainer).resetExposedMenuView(anyBoolean(), anyBoolean());
+ }
+
+ @Test
public void testChangeDensityOrFontScale() {
NotificationGuts guts = spy(new NotificationGuts(mContext));
when(guts.post(any())).thenAnswer(invocation -> {