Merge "[Ongoing call] Don't show the time if the notification's when value isn't valid." into sc-dev am: 3ad556f672
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15177730 Change-Id: Ia61a5ab77858fcb68998bb25c112d6367696bb1c
This commit is contained in:
@@ -20,6 +20,7 @@ import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
|
||||
import android.widget.Chronometer
|
||||
import androidx.annotation.UiThread
|
||||
|
||||
/**
|
||||
* A [Chronometer] specifically for the ongoing call chip in the status bar.
|
||||
@@ -46,10 +47,10 @@ class OngoingCallChronometer @JvmOverloads constructor(
|
||||
|
||||
// Minimum width that the text view can be. Corresponds with the largest number width seen so
|
||||
// far.
|
||||
var minimumTextWidth: Int = 0
|
||||
private var minimumTextWidth: Int = 0
|
||||
|
||||
// True if the text is too long for the space available, so the text should be hidden.
|
||||
var shouldHideText: Boolean = false
|
||||
private var shouldHideText: Boolean = false
|
||||
|
||||
override fun setBase(base: Long) {
|
||||
// These variables may have changed during the previous call, so re-set them before the new
|
||||
@@ -60,6 +61,13 @@ class OngoingCallChronometer @JvmOverloads constructor(
|
||||
super.setBase(base)
|
||||
}
|
||||
|
||||
/** Sets whether this view should hide its text or not. */
|
||||
@UiThread
|
||||
fun setShouldHideText(shouldHideText: Boolean) {
|
||||
this.shouldHideText = shouldHideText
|
||||
requestLayout()
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
if (shouldHideText) {
|
||||
setMeasuredDimension(0, 0)
|
||||
|
||||
@@ -172,10 +172,16 @@ class OngoingCallController @Inject constructor(
|
||||
currentChipView?.findViewById<View>(R.id.ongoing_call_chip_background)
|
||||
|
||||
if (currentChipView != null && timeView != null && backgroundView != null) {
|
||||
timeView.base = currentCallNotificationInfo.callStartTime -
|
||||
System.currentTimeMillis() +
|
||||
systemClock.elapsedRealtime()
|
||||
timeView.start()
|
||||
if (currentCallNotificationInfo.hasValidStartTime()) {
|
||||
timeView.setShouldHideText(false)
|
||||
timeView.base = currentCallNotificationInfo.callStartTime -
|
||||
systemClock.currentTimeMillis() +
|
||||
systemClock.elapsedRealtime()
|
||||
timeView.start()
|
||||
} else {
|
||||
timeView.setShouldHideText(true)
|
||||
timeView.stop()
|
||||
}
|
||||
|
||||
currentCallNotificationInfo.intent?.let { intent ->
|
||||
currentChipView.setOnClickListener {
|
||||
@@ -260,7 +266,9 @@ class OngoingCallController @Inject constructor(
|
||||
@VisibleForTesting
|
||||
fun tearDownChipView() = chipView?.getTimeView()?.stop()
|
||||
|
||||
private fun View.getTimeView(): Chronometer? = this.findViewById(R.id.ongoing_call_chip_time)
|
||||
private fun View.getTimeView(): OngoingCallChronometer? {
|
||||
return this.findViewById(R.id.ongoing_call_chip_time)
|
||||
}
|
||||
|
||||
private data class CallNotificationInfo(
|
||||
val key: String,
|
||||
@@ -269,7 +277,13 @@ class OngoingCallController @Inject constructor(
|
||||
val uid: Int,
|
||||
/** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
|
||||
val isOngoing: Boolean
|
||||
)
|
||||
) {
|
||||
/**
|
||||
* Returns true if the notification information has a valid call start time.
|
||||
* See b/192379214.
|
||||
*/
|
||||
fun hasValidStartTime(): Boolean = callStartTime > 0
|
||||
}
|
||||
}
|
||||
|
||||
private fun isCallNotification(entry: NotificationEntry): Boolean {
|
||||
|
||||
@@ -132,6 +132,26 @@ class OngoingCallChronometerTest : SysuiTestCase() {
|
||||
assertThat(textView.measuredWidth).isGreaterThan(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setShouldHideText_true_textHidden() {
|
||||
textView.setShouldHideText(true)
|
||||
measureTextView()
|
||||
|
||||
assertThat(textView.measuredWidth).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setShouldHideText_false_textShown() {
|
||||
// First, set to true so that setting it to false will definitely have an effect.
|
||||
textView.setShouldHideText(true)
|
||||
measureTextView()
|
||||
|
||||
textView.setShouldHideText(false)
|
||||
measureTextView()
|
||||
|
||||
assertThat(textView.measuredWidth).isGreaterThan(0)
|
||||
}
|
||||
|
||||
private fun setTextAndMeasure(text: String) {
|
||||
textView.text = text
|
||||
measureTextView()
|
||||
|
||||
@@ -153,6 +153,37 @@ class OngoingCallControllerTest : SysuiTestCase() {
|
||||
createCallNotifEntry(ongoingCallStyle, nullContentIntent = true))
|
||||
}
|
||||
|
||||
/** Regression test for b/192379214. */
|
||||
@Test
|
||||
fun onEntryUpdated_notificationWhenIsZero_timeHidden() {
|
||||
val notification = NotificationEntryBuilder(createOngoingCallNotifEntry())
|
||||
notification.modifyNotification(context).setWhen(0)
|
||||
|
||||
notifCollectionListener.onEntryUpdated(notification.build())
|
||||
chipView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||
)
|
||||
|
||||
assertThat(chipView.findViewById<View>(R.id.ongoing_call_chip_time)?.measuredWidth)
|
||||
.isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onEntryUpdated_notificationWhenIsValid_timeShown() {
|
||||
val notification = NotificationEntryBuilder(createOngoingCallNotifEntry())
|
||||
notification.modifyNotification(context).setWhen(clock.currentTimeMillis())
|
||||
|
||||
notifCollectionListener.onEntryUpdated(notification.build())
|
||||
chipView.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||
)
|
||||
|
||||
assertThat(chipView.findViewById<View>(R.id.ongoing_call_chip_time)?.measuredWidth)
|
||||
.isGreaterThan(0)
|
||||
}
|
||||
|
||||
/**
|
||||
* If a call notification is never added before #onEntryRemoved is called, then the listener
|
||||
* should never be notified.
|
||||
|
||||
Reference in New Issue
Block a user