[Ongoing Call] Add an option to disable tapping the chip while in

immersive mode.

Bug: 195839150
Test: Manual
Test: atset OngoingCallControllerTest
Change-Id: I84ccce47bb3f23c208063e6537154d405d3fc900
This commit is contained in:
Caitlin Cassidy
2021-10-06 21:36:31 +00:00
parent 53a1d2e0e0
commit de3c5c0808
5 changed files with 120 additions and 30 deletions

View File

@@ -48,6 +48,8 @@
<bool name="flag_ongoing_call_in_immersive">false</bool>
<bool name="flag_ongoing_call_in_immersive_chip_tap">true</bool>
<bool name="flag_smartspace">false</bool>
<bool name="flag_smartspace_deduping">true</bool>

View File

@@ -166,6 +166,11 @@ public class FeatureFlags {
&& mFlagReader.isEnabled(R.bool.flag_ongoing_call_in_immersive);
}
public boolean isOngoingCallInImmersiveChipTapEnabled() {
return isOngoingCallInImmersiveEnabled()
&& mFlagReader.isEnabled(R.bool.flag_ongoing_call_in_immersive_chip_tap);
}
public boolean isSmartspaceEnabled() {
return mFlagReader.isEnabled(R.bool.flag_smartspace);
}

View File

@@ -257,7 +257,8 @@ public interface StatusBarDependenciesModule {
OngoingCallLogger logger,
DumpManager dumpManager,
StatusBarWindowController statusBarWindowController,
SwipeStatusBarAwayGestureHandler swipeStatusBarAwayGestureHandler) {
SwipeStatusBarAwayGestureHandler swipeStatusBarAwayGestureHandler,
StatusBarStateController statusBarStateController) {
Optional<StatusBarWindowController> windowController =
featureFlags.isOngoingCallInImmersiveEnabled()
? Optional.of(statusBarWindowController)
@@ -277,8 +278,8 @@ public interface StatusBarDependenciesModule {
logger,
dumpManager,
windowController,
gestureHandler
);
gestureHandler,
statusBarStateController);
ongoingCallController.init();
return ongoingCallController;
}

View File

@@ -34,6 +34,7 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
@@ -61,8 +62,10 @@ class OngoingCallController @Inject constructor(
private val dumpManager: DumpManager,
private val statusBarWindowController: Optional<StatusBarWindowController>,
private val swipeStatusBarAwayGestureHandler: Optional<SwipeStatusBarAwayGestureHandler>,
private val statusBarStateController: StatusBarStateController,
) : CallbackController<OngoingCallListener>, Dumpable {
private var isFullscreen: Boolean = false
/** Non-null if there's an active call notification. */
private var callNotificationInfo: CallNotificationInfo? = null
/** True if the application managing the call is visible to the user. */
@@ -124,6 +127,7 @@ class OngoingCallController @Inject constructor(
dumpManager.registerDumpable(this)
if (featureFlags.isOngoingCallStatusBarChipEnabled) {
notifCollection.addCollectionListener(notifListener)
statusBarStateController.addCallback(statusBarStateListener)
}
}
@@ -177,10 +181,8 @@ class OngoingCallController @Inject constructor(
val currentChipView = chipView
val timeView = currentChipView?.getTimeView()
val backgroundView =
currentChipView?.findViewById<View>(R.id.ongoing_call_chip_background)
if (currentChipView != null && timeView != null && backgroundView != null) {
if (currentChipView != null && timeView != null) {
if (currentCallNotificationInfo.hasValidStartTime()) {
timeView.setShouldHideText(false)
timeView.base = currentCallNotificationInfo.callStartTime -
@@ -191,19 +193,8 @@ class OngoingCallController @Inject constructor(
timeView.setShouldHideText(true)
timeView.stop()
}
updateChipClickListener()
currentCallNotificationInfo.intent?.let { intent ->
currentChipView.setOnClickListener {
logger.logChipClicked()
activityStarter.postStartActivityDismissingKeyguard(
intent,
0,
ActivityLaunchAnimator.Controller.fromView(
backgroundView,
InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP)
)
}
}
setUpUidObserver(currentCallNotificationInfo)
if (!currentCallNotificationInfo.statusBarSwipedAway) {
statusBarWindowController.ifPresent {
@@ -227,6 +218,30 @@ class OngoingCallController @Inject constructor(
}
}
private fun updateChipClickListener() {
if (callNotificationInfo == null) { return }
if (isFullscreen && !featureFlags.isOngoingCallInImmersiveChipTapEnabled) {
chipView?.setOnClickListener(null)
} else {
val currentChipView = chipView
val backgroundView =
currentChipView?.findViewById<View>(R.id.ongoing_call_chip_background)
val intent = callNotificationInfo?.intent
if (currentChipView != null && backgroundView != null && intent != null) {
currentChipView.setOnClickListener {
logger.logChipClicked()
activityStarter.postStartActivityDismissingKeyguard(
intent,
0,
ActivityLaunchAnimator.Controller.fromView(
backgroundView,
InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP)
)
}
}
}
}
/**
* Sets up an [IUidObserver] to monitor the status of the application managing the ongoing call.
*/
@@ -304,14 +319,21 @@ class OngoingCallController @Inject constructor(
* This method updates the status bar window appropriately when the swipe away gesture is
* detected.
*/
private fun onSwipeAwayGestureDetected() {
if (DEBUG) { Log.d(TAG, "Swipe away gesture detected") }
callNotificationInfo = callNotificationInfo?.copy(statusBarSwipedAway = true)
statusBarWindowController.ifPresent {
it.setOngoingProcessRequiresStatusBarVisible(false)
}
swipeStatusBarAwayGestureHandler.ifPresent {
it.removeOnGestureDetectedCallback(TAG)
private fun onSwipeAwayGestureDetected() {
if (DEBUG) { Log.d(TAG, "Swipe away gesture detected") }
callNotificationInfo = callNotificationInfo?.copy(statusBarSwipedAway = true)
statusBarWindowController.ifPresent {
it.setOngoingProcessRequiresStatusBarVisible(false)
}
swipeStatusBarAwayGestureHandler.ifPresent {
it.removeOnGestureDetectedCallback(TAG)
}
}
private val statusBarStateListener = object : StatusBarStateController.StateListener {
override fun onFullscreenStateChanged(isFullscreen: Boolean) {
this@OngoingCallController.isFullscreen = isFullscreen
updateChipClickListener()
}
}

View File

@@ -36,6 +36,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
@@ -82,11 +83,13 @@ class OngoingCallControllerTest : SysuiTestCase() {
private lateinit var controller: OngoingCallController
private lateinit var notifCollectionListener: NotifCollectionListener
@Mock private lateinit var mockFeatureFlags: FeatureFlags
@Mock private lateinit var mockSwipeStatusBarAwayGestureHandler: SwipeStatusBarAwayGestureHandler
@Mock private lateinit var mockOngoingCallListener: OngoingCallListener
@Mock private lateinit var mockActivityStarter: ActivityStarter
@Mock private lateinit var mockIActivityManager: IActivityManager
@Mock private lateinit var mockStatusBarWindowController: StatusBarWindowController
@Mock private lateinit var mockStatusBarStateController: StatusBarStateController
private lateinit var chipView: View
@@ -98,13 +101,12 @@ class OngoingCallControllerTest : SysuiTestCase() {
}
MockitoAnnotations.initMocks(this)
val featureFlags = mock(FeatureFlags::class.java)
`when`(featureFlags.isOngoingCallStatusBarChipEnabled).thenReturn(true)
`when`(mockFeatureFlags.isOngoingCallStatusBarChipEnabled).thenReturn(true)
val notificationCollection = mock(CommonNotifCollection::class.java)
controller = OngoingCallController(
notificationCollection,
featureFlags,
mockFeatureFlags,
clock,
mockActivityStarter,
mainExecutor,
@@ -113,7 +115,8 @@ class OngoingCallControllerTest : SysuiTestCase() {
DumpManager(),
Optional.of(mockStatusBarWindowController),
Optional.of(mockSwipeStatusBarAwayGestureHandler),
)
mockStatusBarStateController,
)
controller.init()
controller.addCallback(mockOngoingCallListener)
controller.setChipView(chipView)
@@ -455,6 +458,56 @@ class OngoingCallControllerTest : SysuiTestCase() {
// Other tests for notifyChipVisibilityChanged are in [OngoingCallLogger], since
// [OngoingCallController.notifyChipVisibilityChanged] just delegates to that class.
@Test
fun callNotificationAdded_chipIsClickable() {
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
assertThat(chipView.hasOnClickListeners()).isTrue()
}
@Test
fun fullscreenIsTrue_thenCallNotificationAdded_chipNotClickable() {
`when`(mockFeatureFlags.isOngoingCallInImmersiveChipTapEnabled).thenReturn(false)
getStateListener().onFullscreenStateChanged(/* isFullscreen= */ true)
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
assertThat(chipView.hasOnClickListeners()).isFalse()
}
@Test
fun callNotificationAdded_thenFullscreenIsTrue_chipNotClickable() {
`when`(mockFeatureFlags.isOngoingCallInImmersiveChipTapEnabled).thenReturn(false)
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
getStateListener().onFullscreenStateChanged(/* isFullscreen= */ true)
assertThat(chipView.hasOnClickListeners()).isFalse()
}
@Test
fun fullscreenChangesToFalse_chipClickable() {
`when`(mockFeatureFlags.isOngoingCallInImmersiveChipTapEnabled).thenReturn(false)
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
// First, update to true
getStateListener().onFullscreenStateChanged(/* isFullscreen= */ true)
// Then, update to false
getStateListener().onFullscreenStateChanged(/* isFullscreen= */ false)
assertThat(chipView.hasOnClickListeners()).isTrue()
}
@Test
fun fullscreenIsTrue_butChipClickInImmersiveEnabled_chipClickable() {
`when`(mockFeatureFlags.isOngoingCallInImmersiveChipTapEnabled).thenReturn(true)
notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
getStateListener().onFullscreenStateChanged(/* isFullscreen= */ true)
assertThat(chipView.hasOnClickListeners()).isTrue()
}
private fun createOngoingCallNotifEntry() = createCallNotifEntry(ongoingCallStyle)
private fun createScreeningCallNotifEntry() = createCallNotifEntry(screeningCallStyle)
@@ -479,6 +532,13 @@ class OngoingCallControllerTest : SysuiTestCase() {
}
private fun createNotCallNotifEntry() = NotificationEntryBuilder().build()
private fun getStateListener(): StatusBarStateController.StateListener {
val statusBarStateListenerCaptor = ArgumentCaptor.forClass(
StatusBarStateController.StateListener::class.java)
verify(mockStatusBarStateController).addCallback(statusBarStateListenerCaptor.capture())
return statusBarStateListenerCaptor.value!!
}
}
private val person = Person.Builder().setName("name").build()