Merge changes from topics "caitlinshk-csi-getdisplayid", "caitlinshk-csi-wakeupforfsi" into udc-qpr-dev

* changes:
  [CS] Have ActivityStarterImpl inject display ID directly.
  [CS] Have SBNotifActivityStarter inject display ID directly.
  [CS] Move CS#wakeUpForFullScreenIntent to PowerInteractor.
This commit is contained in:
Caitlin Shkuratov
2023-07-12 23:01:07 +00:00
committed by Android (Google) Code Review
12 changed files with 132 additions and 40 deletions

View File

@@ -20,6 +20,7 @@ package com.android.systemui.power.domain.interactor
import android.os.PowerManager
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.data.repository.PowerRepository
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
@@ -32,6 +33,7 @@ class PowerInteractor
@Inject
constructor(
private val repository: PowerRepository,
private val keyguardRepository: KeyguardRepository,
private val falsingCollector: FalsingCollector,
private val screenOffAnimationController: ScreenOffAnimationController,
private val statusBarStateController: StatusBarStateController,
@@ -54,4 +56,21 @@ constructor(
falsingCollector.onScreenOnFromTouch()
}
}
/**
* Wakes up the device if the device was dozing or going to sleep in order to display a
* full-screen intent.
*/
fun wakeUpForFullScreenIntent() {
if (
keyguardRepository.wakefulness.value.isStartingToSleep() ||
statusBarStateController.isDozing
) {
repository.wakeUp(why = FSI_WAKE_WHY, wakeReason = PowerManager.WAKE_REASON_APPLICATION)
}
}
companion object {
private const val FSI_WAKE_WHY = "full_screen_intent"
}
}

View File

@@ -37,6 +37,7 @@ import com.android.systemui.animation.DelegateLaunchAnimatorController
import com.android.systemui.assist.AssistManager
import com.android.systemui.camera.CameraIntents.Companion.isInsecureCameraIntent
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.DisplayId
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
@@ -72,6 +73,7 @@ constructor(
private val notifShadeWindowControllerLazy: Lazy<NotificationShadeWindowController>,
private val activityLaunchAnimator: ActivityLaunchAnimator,
private val context: Context,
@DisplayId private val displayId: Int,
private val lockScreenUserManager: NotificationLockscreenUserManager,
private val statusBarWindowController: StatusBarWindowController,
private val wakefulnessLifecycle: WakefulnessLifecycle,
@@ -471,9 +473,7 @@ constructor(
intent.getPackage()
) { adapter: RemoteAnimationAdapter? ->
val options =
ActivityOptions(
CentralSurfaces.getActivityOptions(centralSurfaces!!.displayId, adapter)
)
ActivityOptions(CentralSurfaces.getActivityOptions(displayId, adapter))
// We know that the intent of the caller is to dismiss the keyguard and
// this runnable is called right after the keyguard is solved, so we tell
@@ -596,7 +596,7 @@ constructor(
val options =
ActivityOptions(
CentralSurfaces.getActivityOptions(
centralSurfaces!!.displayId,
displayId,
animationAdapter
)
)
@@ -762,7 +762,7 @@ constructor(
TaskStackBuilder.create(context)
.addNextIntent(intent)
.startActivities(
CentralSurfaces.getActivityOptions(centralSurfaces!!.displayId, adapter),
CentralSurfaces.getActivityOptions(displayId, adapter),
userHandle
)
}

View File

@@ -355,15 +355,11 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
void updateNotificationPanelTouchState();
int getDisplayId();
int getRotation();
@VisibleForTesting
void setBarStateForTest(int state);
void wakeUpForFullScreenIntent();
void showTransientUnchecked();
void clearTransient();

View File

@@ -1772,7 +1772,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
try {
EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
sbn.getKey());
wakeUpForFullScreenIntent();
mPowerInteractor.wakeUpForFullScreenIntent();
ActivityOptions opts = ActivityOptions.makeBasic();
opts.setPendingIntentBackgroundActivityStartMode(
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
@@ -1785,16 +1785,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mHeadsUpManager.releaseAllImmediately();
}
@Override
public void wakeUpForFullScreenIntent() {
if (isGoingToSleep() || mDozing) {
mPowerManager.wakeUp(
SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_APPLICATION,
"com.android.systemui:full_screen_intent");
}
}
/**
* Called when another window is about to transfer it's input focus.
*/
@@ -2106,11 +2096,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
return mDisplay.getRotation();
}
@Override
public int getDisplayId() {
return mDisplayId;
}
@Override
public void readyForKeyguardDone() {
mStatusBarKeyguardViewManager.readyForKeyguardDone();

View File

@@ -54,8 +54,10 @@ import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.EventLogTags;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeViewController;
@@ -94,6 +96,7 @@ import javax.inject.Inject;
class StatusBarNotificationActivityStarter implements NotificationActivityStarter {
private final Context mContext;
private final int mDisplayId;
private final Handler mMainThreadHandler;
private final Executor mUiBgExecutor;
@@ -120,12 +123,12 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
private final MetricsLogger mMetricsLogger;
private final StatusBarNotificationActivityStarterLogger mLogger;
private final CentralSurfaces mCentralSurfaces;
private final NotificationPresenter mPresenter;
private final ShadeViewController mShadeViewController;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final ActivityLaunchAnimator mActivityLaunchAnimator;
private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
private final PowerInteractor mPowerInteractor;
private final UserTracker mUserTracker;
private final OnUserInteractionCallback mOnUserInteractionCallback;
@@ -134,6 +137,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
@Inject
StatusBarNotificationActivityStarter(
Context context,
@DisplayId int displayId,
Handler mainThreadHandler,
Executor uiBgExecutor,
NotificationVisibilityProvider visibilityProvider,
@@ -156,16 +160,17 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
MetricsLogger metricsLogger,
StatusBarNotificationActivityStarterLogger logger,
OnUserInteractionCallback onUserInteractionCallback,
CentralSurfaces centralSurfaces,
NotificationPresenter presenter,
ShadeViewController shadeViewController,
NotificationShadeWindowController notificationShadeWindowController,
ActivityLaunchAnimator activityLaunchAnimator,
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider,
LaunchFullScreenIntentProvider launchFullScreenIntentProvider,
PowerInteractor powerInteractor,
FeatureFlags featureFlags,
UserTracker userTracker) {
mContext = context;
mDisplayId = displayId;
mMainThreadHandler = mainThreadHandler;
mUiBgExecutor = uiBgExecutor;
mVisibilityProvider = visibilityProvider;
@@ -190,12 +195,11 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
mMetricsLogger = metricsLogger;
mLogger = logger;
mOnUserInteractionCallback = onUserInteractionCallback;
// TODO: use KeyguardStateController#isOccluded to remove this dependency
mCentralSurfaces = centralSurfaces;
mPresenter = presenter;
mShadeViewController = shadeViewController;
mActivityLaunchAnimator = activityLaunchAnimator;
mNotificationAnimationProvider = notificationAnimationProvider;
mPowerInteractor = powerInteractor;
mUserTracker = userTracker;
launchFullScreenIntentProvider.registerListener(entry -> launchFullScreenIntent(entry));
@@ -452,11 +456,11 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
long eventTime = row.getAndResetLastActionUpTime();
Bundle options = eventTime > 0
? getActivityOptions(
mCentralSurfaces.getDisplayId(),
mDisplayId,
adapter,
mKeyguardStateController.isShowing(),
eventTime)
: getActivityOptions(mCentralSurfaces.getDisplayId(), adapter);
: getActivityOptions(mDisplayId, adapter);
int result = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
null, null, options);
mLogger.logSendPendingIntent(entry, intent, result);
@@ -491,7 +495,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
(adapter) -> TaskStackBuilder.create(mContext)
.addNextIntentWithParentStack(intent)
.startActivities(getActivityOptions(
mCentralSurfaces.getDisplayId(),
mDisplayId,
adapter),
new UserHandle(UserHandle.getUserId(appUid))));
});
@@ -539,7 +543,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
intent.getPackage(),
(adapter) -> tsb.startActivities(
getActivityOptions(mCentralSurfaces.getDisplayId(), adapter),
getActivityOptions(mDisplayId, adapter),
mUserTracker.getUserHandle()));
});
return true;
@@ -592,7 +596,7 @@ class StatusBarNotificationActivityStarter implements NotificationActivityStarte
try {
EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
entry.getKey());
mCentralSurfaces.wakeUpForFullScreenIntent();
mPowerInteractor.wakeUpForFullScreenIntent();
ActivityOptions options = ActivityOptions.makeBasic();
options.setPendingIntentBackgroundActivityStartMode(

View File

@@ -21,6 +21,10 @@ import android.os.PowerManager
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.WakeSleepReason
import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
@@ -44,6 +48,7 @@ class PowerInteractorTest : SysuiTestCase() {
private lateinit var underTest: PowerInteractor
private lateinit var repository: FakePowerRepository
private val keyguardRepository = FakeKeyguardRepository()
@Mock private lateinit var falsingCollector: FalsingCollector
@Mock private lateinit var screenOffAnimationController: ScreenOffAnimationController
@Mock private lateinit var statusBarStateController: StatusBarStateController
@@ -59,6 +64,7 @@ class PowerInteractorTest : SysuiTestCase() {
underTest =
PowerInteractor(
repository,
keyguardRepository,
falsingCollector,
screenOffAnimationController,
statusBarStateController,
@@ -125,6 +131,57 @@ class PowerInteractorTest : SysuiTestCase() {
verify(falsingCollector).onScreenOnFromTouch()
}
@Test
fun wakeUpForFullScreenIntent_notGoingToSleepAndNotDozing_notWoken() {
keyguardRepository.setWakefulnessModel(
WakefulnessModel(
state = WakefulnessState.AWAKE,
lastWakeReason = WakeSleepReason.OTHER,
lastSleepReason = WakeSleepReason.OTHER,
)
)
whenever(statusBarStateController.isDozing).thenReturn(false)
underTest.wakeUpForFullScreenIntent()
assertThat(repository.lastWakeWhy).isNull()
assertThat(repository.lastWakeReason).isNull()
}
@Test
fun wakeUpForFullScreenIntent_startingToSleep_woken() {
keyguardRepository.setWakefulnessModel(
WakefulnessModel(
state = WakefulnessState.STARTING_TO_SLEEP,
lastWakeReason = WakeSleepReason.OTHER,
lastSleepReason = WakeSleepReason.OTHER,
)
)
whenever(statusBarStateController.isDozing).thenReturn(false)
underTest.wakeUpForFullScreenIntent()
assertThat(repository.lastWakeWhy).isNotNull()
assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_APPLICATION)
}
@Test
fun wakeUpForFullScreenIntent_dozing_woken() {
whenever(statusBarStateController.isDozing).thenReturn(true)
keyguardRepository.setWakefulnessModel(
WakefulnessModel(
state = WakefulnessState.AWAKE,
lastWakeReason = WakeSleepReason.OTHER,
lastSleepReason = WakeSleepReason.OTHER,
)
)
underTest.wakeUpForFullScreenIntent()
assertThat(repository.lastWakeWhy).isNotNull()
assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_APPLICATION)
}
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
}

View File

@@ -28,6 +28,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dock.DockManager
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.data.repository.FakePowerRepository
@@ -89,6 +90,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
dockManager,
PowerInteractor(
powerRepository,
FakeKeyguardRepository(),
falsingCollector,
screenOffAnimationController,
statusBarStateController,

View File

@@ -101,16 +101,18 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
@Mock lateinit var activityStarter: ActivityStarter
@Mock lateinit var transitionControllerCallback: LockscreenShadeTransitionController.Callback
private val disableFlagsRepository = FakeDisableFlagsRepository()
private val keyguardRepository = FakeKeyguardRepository()
private val shadeInteractor = ShadeInteractor(
testScope.backgroundScope,
disableFlagsRepository,
keyguardRepository = FakeKeyguardRepository(),
keyguardRepository,
userSetupRepository = FakeUserSetupRepository(),
deviceProvisionedController = mock(),
userInteractor = mock(),
)
private val powerInteractor = PowerInteractor(
FakePowerRepository(),
keyguardRepository,
FalsingCollectorFake(),
screenOffAnimationController = mock(),
statusBarStateController = mock(),

View File

@@ -58,6 +58,7 @@ class NotificationShelfInteractorTest : SysuiTestCase() {
private val powerInteractor =
PowerInteractor(
powerRepository,
keyguardRepository,
FalsingCollectorFake(),
screenOffAnimationController,
statusBarStateController,

View File

@@ -69,6 +69,7 @@ class NotificationShelfViewModelTest : SysuiTestCase() {
private val powerInteractor by lazy {
PowerInteractor(
powerRepository,
keyguardRepository,
FalsingCollectorFake(),
screenOffAnimationController,
statusBarStateController,

View File

@@ -95,6 +95,7 @@ class ActivityStarterImplTest : SysuiTestCase() {
Lazy { notifShadeWindowController },
activityLaunchAnimator,
context,
DISPLAY_ID,
lockScreenUserManager,
statusBarWindowController,
wakefulnessLifecycle,
@@ -274,4 +275,8 @@ class ActivityStarterImplTest : SysuiTestCase() {
mainExecutor.runAllReady()
verify(statusBarStateController).setLeaveOpenOnKeyguardHide(true)
}
private companion object {
private const val DISPLAY_ID = 0
}
}

View File

@@ -21,6 +21,8 @@ import static android.service.notification.NotificationListenerService.REASON_CL
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.AdditionalAnswers.answerVoid;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -61,10 +63,14 @@ import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.data.repository.FakePowerRepository;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.shade.ShadeControllerImpl;
@@ -110,6 +116,8 @@ import java.util.Optional;
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private static final int DISPLAY_ID = 0;
@Mock
private AssistManager mAssistManager;
@Mock
@@ -118,13 +126,12 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private NotificationClickNotifier mClickNotifier;
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock private ScreenOffAnimationController mScreenOffAnimationController;
@Mock
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock
private NotificationRemoteInputManager mRemoteInputManager;
@Mock
private CentralSurfaces mCentralSurfaces;
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private NotificationInterruptStateProvider mNotificationInterruptStateProvider;
@@ -150,6 +157,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private ActivityLaunchAnimator mActivityLaunchAnimator;
@Mock
private InteractionJankMonitor mJankMonitor;
private FakePowerRepository mPowerRepository;
private PowerInteractor mPowerInteractor;
@Mock
private UserTracker mUserTracker;
private final FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -199,6 +208,14 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
when(mUserTracker.getUserHandle()).thenReturn(
UserHandle.of(ActivityManager.getCurrentUser()));
mPowerRepository = new FakePowerRepository();
mPowerInteractor = new PowerInteractor(
mPowerRepository,
new FakeKeyguardRepository(),
new FalsingCollectorFake(),
mScreenOffAnimationController,
mStatusBarStateController);
HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class);
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider =
new NotificationLaunchAnimatorControllerProvider(
@@ -209,6 +226,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mNotificationActivityStarter =
new StatusBarNotificationActivityStarter(
getContext(),
DISPLAY_ID,
mHandler,
mUiBgExecutor,
mVisibilityProvider,
@@ -231,13 +249,13 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mock(MetricsLogger.class),
mock(StatusBarNotificationActivityStarterLogger.class),
mOnUserInteractionCallback,
mCentralSurfaces,
mock(NotificationPresenter.class),
mock(ShadeViewController.class),
mock(NotificationShadeWindowController.class),
mActivityLaunchAnimator,
notificationAnimationProvider,
mock(LaunchFullScreenIntentProvider.class),
mPowerInteractor,
mock(FeatureFlags.class),
mUserTracker
);
@@ -402,11 +420,13 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
when(entry.getImportance()).thenReturn(NotificationManager.IMPORTANCE_HIGH);
when(entry.getSbn()).thenReturn(sbn);
// WHEN
// WHEN the intent is launched while dozing
when(mStatusBarStateController.isDozing()).thenReturn(true);
mNotificationActivityStarter.launchFullScreenIntent(entry);
// THEN display should try wake up for the full screen intent
verify(mCentralSurfaces).wakeUpForFullScreenIntent();
assertThat(mPowerRepository.getLastWakeReason()).isNotNull();
assertThat(mPowerRepository.getLastWakeWhy()).isNotNull();
}
@Test