blob: 086e5df50f3f34e74c7c8d3eda0d530b7a06ea75 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.phone
import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.StatusBarIconView
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when` as whenever
/**
* Tests for {@link NotificationIconContainer}.
*/
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
class NotificationIconContainerTest : SysuiTestCase() {
private val iconContainer = NotificationIconContainer(context, /* attrs= */ null)
@Test
fun calculateWidthFor_zeroIcons_widthIsZero() {
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 0f),
/* actual= */ 0f)
}
@Test
fun calculateWidthFor_oneIcon_widthForOneIcon() {
iconContainer.setActualPaddingStart(10f)
iconContainer.setActualPaddingEnd(10f)
iconContainer.setIconSize(10);
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 1f),
/* actual= */ 30f)
}
@Test
fun calculateWidthFor_fourIcons_widthForFourIcons() {
iconContainer.setActualPaddingStart(10f)
iconContainer.setActualPaddingEnd(10f)
iconContainer.setIconSize(10);
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 4f),
/* actual= */ 60f)
}
@Test
fun calculateWidthFor_fiveIcons_widthForFourIcons() {
iconContainer.setActualPaddingStart(10f)
iconContainer.setActualPaddingEnd(10f)
iconContainer.setIconSize(10);
assertEquals(/* expected= */ iconContainer.calculateWidthFor(/* numIcons= */ 5f),
/* actual= */ 60f)
}
@Test
fun calculateIconXTranslations_shortShelfOneIcon_atCorrectXWithoutOverflowDot() {
iconContainer.setActualPaddingStart(10f)
iconContainer.setActualPaddingEnd(10f)
iconContainer.setIconSize(10);
val icon = mockStatusBarIcon()
iconContainer.addView(icon)
assertEquals(1, iconContainer.childCount)
val iconState = iconContainer.getIconState(icon)
iconState.iconAppearAmount = 1f
val width = iconContainer.calculateWidthFor(/* numIcons= */ 1f)
iconContainer.setActualLayoutWidth(width.toInt())
iconContainer.calculateIconXTranslations()
assertEquals(10f, iconState.xTranslation)
assertFalse(iconContainer.hasOverflow())
}
@Test
fun calculateIconXTranslations_shortShelfFourIcons_atCorrectXWithoutOverflowDot() {
iconContainer.setActualPaddingStart(10f)
iconContainer.setActualPaddingEnd(10f)
iconContainer.setIconSize(10);
val iconOne = mockStatusBarIcon()
val iconTwo = mockStatusBarIcon()
val iconThree = mockStatusBarIcon()
val iconFour = mockStatusBarIcon()
iconContainer.addView(iconOne)
iconContainer.addView(iconTwo)
iconContainer.addView(iconThree)
iconContainer.addView(iconFour)
assertEquals(4, iconContainer.childCount)
val width = iconContainer.calculateWidthFor(/* numIcons= */ 4f)
iconContainer.setActualLayoutWidth(width.toInt())
iconContainer.calculateIconXTranslations()
assertEquals(10f, iconContainer.getIconState(iconOne).xTranslation)
assertEquals(20f, iconContainer.getIconState(iconTwo).xTranslation)
assertEquals(30f, iconContainer.getIconState(iconThree).xTranslation)
assertEquals(40f, iconContainer.getIconState(iconFour).xTranslation)
assertFalse(iconContainer.hasOverflow())
}
@Test
fun calculateIconXTranslations_shortShelfFiveIcons_atCorrectXWithOverflowDot() {
iconContainer.setActualPaddingStart(10f)
iconContainer.setActualPaddingEnd(10f)
iconContainer.setIconSize(10);
val iconOne = mockStatusBarIcon()
val iconTwo = mockStatusBarIcon()
val iconThree = mockStatusBarIcon()
val iconFour = mockStatusBarIcon()
val iconFive = mockStatusBarIcon()
iconContainer.addView(iconOne)
iconContainer.addView(iconTwo)
iconContainer.addView(iconThree)
iconContainer.addView(iconFour)
iconContainer.addView(iconFive)
assertEquals(5, iconContainer.childCount)
val width = iconContainer.calculateWidthFor(/* numIcons= */ 5f)
iconContainer.setActualLayoutWidth(width.toInt())
iconContainer.calculateIconXTranslations()
assertEquals(10f, iconContainer.getIconState(iconOne).xTranslation)
assertEquals(20f, iconContainer.getIconState(iconTwo).xTranslation)
assertEquals(30f, iconContainer.getIconState(iconThree).xTranslation)
assertTrue(iconContainer.hasOverflow())
}
@Test
fun shouldForceOverflow_appearingAboveSpeedBump_true() {
val forceOverflow = iconContainer.shouldForceOverflow(
/* i= */ 1,
/* speedBumpIndex= */ 0,
/* iconAppearAmount= */ 1f,
/* maxVisibleIcons= */ 5
)
assertTrue(forceOverflow);
}
@Test
fun shouldForceOverflow_moreThanMaxVisible_true() {
val forceOverflow = iconContainer.shouldForceOverflow(
/* i= */ 10,
/* speedBumpIndex= */ 11,
/* iconAppearAmount= */ 0f,
/* maxVisibleIcons= */ 5
)
assertTrue(forceOverflow);
}
@Test
fun shouldForceOverflow_belowSpeedBumpAndLessThanMaxVisible_false() {
val forceOverflow = iconContainer.shouldForceOverflow(
/* i= */ 0,
/* speedBumpIndex= */ 11,
/* iconAppearAmount= */ 0f,
/* maxVisibleIcons= */ 5
)
assertFalse(forceOverflow);
}
@Test
fun isOverflowing_lastChildXLessThanLayoutEnd_false() {
val isOverflowing = iconContainer.isOverflowing(
/* isLastChild= */ true,
/* translationX= */ 0f,
/* layoutEnd= */ 10f,
/* iconSize= */ 2f,
)
assertFalse(isOverflowing)
}
@Test
fun isOverflowing_lastChildXEqualToLayoutEnd_true() {
val isOverflowing = iconContainer.isOverflowing(
/* isLastChild= */ true,
/* translationX= */ 10f,
/* layoutEnd= */ 10f,
/* iconSize= */ 2f,
)
assertTrue(isOverflowing)
}
@Test
fun isOverflowing_lastChildXGreaterThanLayoutEnd_true() {
val isOverflowing = iconContainer.isOverflowing(
/* isLastChild= */ true,
/* translationX= */ 20f,
/* layoutEnd= */ 10f,
/* iconSize= */ 2f,
)
assertTrue(isOverflowing)
}
@Test
fun isOverflowing_notLastChildXLessThanDotX_false() {
val isOverflowing = iconContainer.isOverflowing(
/* isLastChild= */ false,
/* translationX= */ 0f,
/* layoutEnd= */ 10f,
/* iconSize= */ 2f,
)
assertFalse(isOverflowing)
}
@Test
fun isOverflowing_notLastChildXGreaterThanDotX_true() {
val isOverflowing = iconContainer.isOverflowing(
/* isLastChild= */ false,
/* translationX= */ 20f,
/* layoutEnd= */ 10f,
/* iconSize= */ 2f,
)
assertTrue(isOverflowing)
}
@Test
fun isOverflowing_notLastChildXEqualToDotX_true() {
val isOverflowing = iconContainer.isOverflowing(
/* isLastChild= */ false,
/* translationX= */ 8f,
/* layoutEnd= */ 10f,
/* iconSize= */ 2f,
)
assertTrue(isOverflowing)
}
private fun mockStatusBarIcon() : StatusBarIconView {
val iconView = mock(StatusBarIconView::class.java)
whenever(iconView.width).thenReturn(10)
val icon = mock(android.graphics.drawable.Icon::class.java)
whenever(iconView.sourceIcon).thenReturn(icon)
val sbn = mock(StatusBarNotification::class.java)
whenever(sbn.groupKey).thenReturn("groupKey")
whenever(iconView.notification).thenReturn(sbn)
return iconView
}
}