summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt67
5 files changed, 112 insertions, 25 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 3562fd1e9134..ed1756aff8c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -55,25 +55,26 @@ constructor(
when (state) {
is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden
is OngoingCallModel.InCall -> {
- // This mimics OngoingCallController#updateChip.
- // TODO(b/332662551): Handle `state.startTimeMs = 0` correctly (see
- // b/192379214 and
- // OngoingCallController.CallNotificationInfo.hasValidStartTime).
- val startTimeInElapsedRealtime =
- state.startTimeMs - systemClock.currentTimeMillis() +
- systemClock.elapsedRealtime()
- OngoingActivityChipModel.Shown.Timer(
- icon =
- Icon.Resource(
- com.android.internal.R.drawable.ic_phone,
- ContentDescription.Resource(
- R.string.ongoing_phone_call_content_description,
- ),
- ),
- colors = ColorsModel.Themed,
- startTimeMs = startTimeInElapsedRealtime,
- getOnClickListener(state),
- )
+ // This block mimics OngoingCallController#updateChip.
+ if (state.startTimeMs <= 0L) {
+ // If the start time is invalid, don't show a timer and show just an
+ // icon. See b/192379214.
+ OngoingActivityChipModel.Shown.IconOnly(
+ icon = phoneIcon,
+ colors = ColorsModel.Themed,
+ getOnClickListener(state),
+ )
+ } else {
+ val startTimeInElapsedRealtime =
+ state.startTimeMs - systemClock.currentTimeMillis() +
+ systemClock.elapsedRealtime()
+ OngoingActivityChipModel.Shown.Timer(
+ icon = phoneIcon,
+ colors = ColorsModel.Themed,
+ startTimeMs = startTimeInElapsedRealtime,
+ getOnClickListener(state),
+ )
+ }
}
}
}
@@ -98,4 +99,14 @@ constructor(
)
}
}
+
+ companion object {
+ private val phoneIcon =
+ Icon.Resource(
+ com.android.internal.R.drawable.ic_phone,
+ ContentDescription.Resource(
+ R.string.ongoing_phone_call_content_description,
+ ),
+ )
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index 57f609b4b534..e8d895c3c266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -36,6 +36,14 @@ sealed class OngoingActivityChipModel {
*/
open val onClickListener: View.OnClickListener?,
) : OngoingActivityChipModel() {
+
+ /** This chip shows only an icon and nothing else. */
+ data class IconOnly(
+ override val icon: Icon,
+ override val colors: ColorsModel,
+ override val onClickListener: View.OnClickListener?,
+ ) : Shown(icon, colors, onClickListener)
+
/** The chip shows a timer, counting up from [startTimeMs]. */
data class Timer(
override val icon: Icon,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 50649a89e588..2c4848776b66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -29,7 +29,8 @@ sealed interface OngoingCallModel {
* @property startTimeMs the time that the phone call started, based on the notification's
* `when` field. Importantly, this time is relative to
* [com.android.systemui.util.time.SystemClock.currentTimeMillis], **not**
- * [com.android.systemui.util.time.SystemClock.elapsedRealtime].
+ * [com.android.systemui.util.time.SystemClock.elapsedRealtime]. This value can be 0 if the
+ * user has started an outgoing call that hasn't been answered yet - see b/192379214.
* @property intent the intent associated with the call notification.
*/
data class InCall(val startTimeMs: Long, val intent: PendingIntent?) : OngoingCallModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index 631befc5dd29..de36e407da84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -161,6 +161,13 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
chipTextView.visibility = View.GONE
}
+ is OngoingActivityChipModel.Shown.IconOnly -> {
+ chipTextView.visibility = View.GONE
+ // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
+ // [Chronometer.start].
+ chipTimeView.stop()
+ chipTimeView.visibility = View.GONE
+ }
}
updateChipTextPadding(chipModel, chipTextView, chipTimeView)
}
@@ -201,7 +208,8 @@ class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBa
// Set as assertive so talkback will announce the countdown
chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
}
- is OngoingActivityChipModel.Shown.Timer -> {
+ is OngoingActivityChipModel.Shown.Timer,
+ is OngoingActivityChipModel.Shown.IconOnly -> {
chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 6cab71fd8e88..1a6b420dace5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -69,7 +69,27 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_inCall_isShownAsTimer() =
+ fun chip_inCall_zeroStartTime_isShownAsIconOnly() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+ }
+
+ @Test
+ fun chip_inCall_negativeStartTime_isShownAsIconOnly() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = -2, intent = null))
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+ }
+
+ @Test
+ fun chip_inCall_positiveStartTime_isShownAsTimer() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -97,7 +117,7 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_iconIsPhone() =
+ fun chip_positiveStartTime_iconIsPhone() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -110,7 +130,20 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_colorsAreThemed() =
+ fun chip_zeroStartTime_iconIsPhone() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+ assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
+ .isEqualTo(com.android.internal.R.drawable.ic_phone)
+ assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
+ .isNotNull()
+ }
+
+ @Test
+ fun chip_positiveStartTime_colorsAreThemed() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -121,6 +154,17 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
+ fun chip_zeroStartTime_colorsAreThemed() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+ assertThat((latest as OngoingActivityChipModel.Shown).colors)
+ .isEqualTo(ColorsModel.Themed)
+ }
+
+ @Test
fun chip_resetsCorrectly() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -159,7 +203,7 @@ class CallChipViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_inCall_validIntent_clickListenerLaunchesIntent() =
+ fun chip_inCall_positiveStartTime_validIntent_clickListenerLaunchesIntent() =
testScope.runTest {
val latest by collectLastValue(underTest.chip)
@@ -172,4 +216,19 @@ class CallChipViewModelTest : SysuiTestCase() {
verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(intent, null)
}
+
+ @Test
+ fun chip_inCall_zeroStartTime_validIntent_clickListenerLaunchesIntent() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ val intent = mock<PendingIntent>()
+ repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = intent))
+ val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
+ assertThat(clickListener).isNotNull()
+
+ clickListener!!.onClick(chipView)
+
+ verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(intent, null)
+ }
}