Merge "New Pipeline: Show media on lockscreen"
This commit is contained in:
committed by
Android (Google) Code Review
commit
21804ecb1c
@@ -16,7 +16,7 @@
|
||||
-->
|
||||
|
||||
<!-- Layout for media controls on the lockscreen -->
|
||||
<com.android.systemui.statusbar.notification.stack.MediaHeaderView
|
||||
<com.android.systemui.statusbar.notification.stack.MediaContainerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -27,7 +27,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||
import com.android.systemui.statusbar.StatusBarState
|
||||
import com.android.systemui.statusbar.SysuiStatusBarStateController
|
||||
import com.android.systemui.statusbar.notification.stack.MediaHeaderView
|
||||
import com.android.systemui.statusbar.notification.stack.MediaContainerView
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import com.android.systemui.util.Utils
|
||||
@@ -96,14 +96,14 @@ class KeyguardMediaController @Inject constructor(
|
||||
/**
|
||||
* single pane media container placed at the top of the notifications list
|
||||
*/
|
||||
var singlePaneContainer: MediaHeaderView? = null
|
||||
var singlePaneContainer: MediaContainerView? = null
|
||||
private set
|
||||
private var splitShadeContainer: ViewGroup? = null
|
||||
|
||||
/**
|
||||
* Attaches media container in single pane mode, situated at the top of the notifications list
|
||||
*/
|
||||
fun attachSinglePaneContainer(mediaView: MediaHeaderView?) {
|
||||
fun attachSinglePaneContainer(mediaView: MediaContainerView?) {
|
||||
val needsListener = singlePaneContainer == null
|
||||
singlePaneContainer = mediaView
|
||||
if (needsListener) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.provider.DeviceConfig
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
|
||||
import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
|
||||
import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
|
||||
@@ -37,6 +38,7 @@ private var sUsePeopleFiltering: Boolean? = null
|
||||
/**
|
||||
* Feature controller for the NOTIFICATIONS_USE_PEOPLE_FILTERING config.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class NotificationSectionsFeatureManager @Inject constructor(
|
||||
val proxy: DeviceConfigProxy,
|
||||
val context: Context
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.notification.collection.render
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.statusbar.notification.stack.MediaContainerView
|
||||
import javax.inject.Inject
|
||||
|
||||
@SysUISingleton
|
||||
class MediaContainerController @Inject constructor(
|
||||
private val layoutInflater: LayoutInflater
|
||||
) : NodeController {
|
||||
|
||||
override val nodeLabel = "MediaContainer"
|
||||
var mediaContainerView: MediaContainerView? = null
|
||||
private set
|
||||
|
||||
fun reinflateView(parent: ViewGroup) {
|
||||
var oldPos = -1
|
||||
mediaContainerView?.let { _view ->
|
||||
_view.transientContainer?.removeView(_view)
|
||||
if (_view.parent === parent) {
|
||||
oldPos = parent.indexOfChild(_view)
|
||||
parent.removeView(_view)
|
||||
}
|
||||
}
|
||||
val inflated = layoutInflater.inflate(
|
||||
R.layout.keyguard_media_container,
|
||||
parent,
|
||||
false /* attachToRoot */)
|
||||
as MediaContainerView
|
||||
if (oldPos != -1) {
|
||||
parent.addView(inflated, oldPos)
|
||||
}
|
||||
mediaContainerView = inflated
|
||||
}
|
||||
|
||||
override val view: View
|
||||
get() = mediaContainerView!!
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.render
|
||||
|
||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
@@ -32,6 +33,8 @@ import com.android.systemui.util.traceSection
|
||||
* need to present in the shade, notably the section headers.
|
||||
*/
|
||||
class NodeSpecBuilder(
|
||||
private val mediaContainerController: MediaContainerController,
|
||||
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
|
||||
private val viewBarn: NotifViewBarn
|
||||
) {
|
||||
fun buildNodeSpec(
|
||||
@@ -39,6 +42,13 @@ class NodeSpecBuilder(
|
||||
notifList: List<ListEntry>
|
||||
): NodeSpec = traceSection("NodeSpecBuilder.buildNodeSpec") {
|
||||
val root = NodeSpecImpl(null, rootController)
|
||||
|
||||
// The media container should be added as the first child of the root node
|
||||
// TODO: Perhaps the node spec building process should be more of a pipeline of its own?
|
||||
if (sectionsFeatureManager.isMediaControlsEnabled()) {
|
||||
root.children.add(NodeSpecImpl(root, mediaContainerController))
|
||||
}
|
||||
|
||||
var currentSection: NotifSection? = null
|
||||
val prevSections = mutableSetOf<NotifSection?>()
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.collection.render
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
@@ -33,13 +34,15 @@ class ShadeViewManager constructor(
|
||||
context: Context,
|
||||
listContainer: NotificationListContainer,
|
||||
private val stackController: NotifStackController,
|
||||
mediaContainerController: MediaContainerController,
|
||||
featureManager: NotificationSectionsFeatureManager,
|
||||
logger: ShadeViewDifferLogger,
|
||||
private val viewBarn: NotifViewBarn
|
||||
) {
|
||||
// We pass a shim view here because the listContainer may not actually have a view associated
|
||||
// with it and the differ never actually cares about the root node's view.
|
||||
private val rootController = RootNodeController(listContainer, View(context))
|
||||
private val specBuilder = NodeSpecBuilder(viewBarn)
|
||||
private val specBuilder = NodeSpecBuilder(mediaContainerController, featureManager, viewBarn)
|
||||
private val viewDiffer = ShadeViewDiffer(rootController, logger)
|
||||
|
||||
/** Method for attaching this manager to the pipeline. */
|
||||
@@ -68,6 +71,8 @@ class ShadeViewManager constructor(
|
||||
class ShadeViewManagerFactory @Inject constructor(
|
||||
private val context: Context,
|
||||
private val logger: ShadeViewDifferLogger,
|
||||
private val mediaContainerController: MediaContainerController,
|
||||
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
|
||||
private val viewBarn: NotifViewBarn
|
||||
) {
|
||||
fun create(listContainer: NotificationListContainer, stackController: NotifStackController) =
|
||||
@@ -75,6 +80,8 @@ class ShadeViewManagerFactory @Inject constructor(
|
||||
context,
|
||||
listContainer,
|
||||
stackController,
|
||||
mediaContainerController,
|
||||
sectionsFeatureManager,
|
||||
logger,
|
||||
viewBarn)
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||
/**
|
||||
* Root view to insert Lock screen media controls into the notification stack.
|
||||
*/
|
||||
public class MediaHeaderView extends ExpandableView {
|
||||
public class MediaContainerView extends ExpandableView {
|
||||
|
||||
public MediaHeaderView(Context context, AttributeSet attrs) {
|
||||
public MediaContainerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@@ -16,17 +16,15 @@
|
||||
package com.android.systemui.statusbar.notification.stack
|
||||
|
||||
import android.annotation.ColorInt
|
||||
import android.annotation.LayoutRes
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.media.KeyguardMediaController
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.StatusBarState
|
||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags
|
||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
|
||||
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
|
||||
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
|
||||
import com.android.systemui.statusbar.notification.collection.render.ShadeViewManager
|
||||
import com.android.systemui.statusbar.notification.dagger.AlertingHeader
|
||||
@@ -60,6 +58,7 @@ class NotificationSectionsManager @Inject internal constructor(
|
||||
private val sectionsFeatureManager: NotificationSectionsFeatureManager,
|
||||
private val logger: NotificationSectionsLogger,
|
||||
private val notifPipelineFlags: NotifPipelineFlags,
|
||||
private val mediaContainerController: MediaContainerController,
|
||||
@IncomingHeader private val incomingHeaderController: SectionHeaderController,
|
||||
@PeopleHeader private val peopleHeaderController: SectionHeaderController,
|
||||
@AlertingHeader private val alertingHeaderController: SectionHeaderController,
|
||||
@@ -68,7 +67,7 @@ class NotificationSectionsManager @Inject internal constructor(
|
||||
|
||||
private val configurationListener = object : ConfigurationController.ConfigurationListener {
|
||||
override fun onLocaleListChanged() {
|
||||
reinflateViews(LayoutInflater.from(parent.context))
|
||||
reinflateViews()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,39 +90,19 @@ class NotificationSectionsManager @Inject internal constructor(
|
||||
val peopleHeaderView: SectionHeaderView?
|
||||
get() = peopleHeaderController.headerView
|
||||
|
||||
@get:VisibleForTesting
|
||||
var mediaControlsView: MediaHeaderView? = null
|
||||
private set
|
||||
@VisibleForTesting
|
||||
val mediaControlsView: MediaContainerView?
|
||||
get() = mediaContainerController.mediaContainerView
|
||||
|
||||
/** Must be called before use. */
|
||||
fun initialize(parent: NotificationStackScrollLayout, layoutInflater: LayoutInflater) {
|
||||
fun initialize(parent: NotificationStackScrollLayout) {
|
||||
check(!initialized) { "NotificationSectionsManager already initialized" }
|
||||
initialized = true
|
||||
this.parent = parent
|
||||
reinflateViews(layoutInflater)
|
||||
reinflateViews()
|
||||
configurationController.addCallback(configurationListener)
|
||||
}
|
||||
|
||||
private fun <T : ExpandableView> reinflateView(
|
||||
view: T?,
|
||||
layoutInflater: LayoutInflater,
|
||||
@LayoutRes layoutResId: Int
|
||||
): T {
|
||||
var oldPos = -1
|
||||
view?.let {
|
||||
view.transientContainer?.removeView(view)
|
||||
if (view.parent === parent) {
|
||||
oldPos = parent.indexOfChild(view)
|
||||
parent.removeView(view)
|
||||
}
|
||||
}
|
||||
val inflated = layoutInflater.inflate(layoutResId, parent, false) as T
|
||||
if (oldPos != -1) {
|
||||
parent.addView(inflated, oldPos)
|
||||
}
|
||||
return inflated
|
||||
}
|
||||
|
||||
fun createSectionsForBuckets(): Array<NotificationSection> =
|
||||
sectionsFeatureManager.getNotificationBuckets()
|
||||
.map { NotificationSection(parent, it) }
|
||||
@@ -132,13 +111,12 @@ class NotificationSectionsManager @Inject internal constructor(
|
||||
/**
|
||||
* Reinflates the entire notification header, including all decoration views.
|
||||
*/
|
||||
fun reinflateViews(layoutInflater: LayoutInflater) {
|
||||
fun reinflateViews() {
|
||||
silentHeaderController.reinflateView(parent)
|
||||
alertingHeaderController.reinflateView(parent)
|
||||
peopleHeaderController.reinflateView(parent)
|
||||
incomingHeaderController.reinflateView(parent)
|
||||
mediaControlsView =
|
||||
reinflateView(mediaControlsView, layoutInflater, R.layout.keyguard_media_header)
|
||||
mediaContainerController.reinflateView(parent)
|
||||
keyguardMediaController.attachSinglePaneContainer(mediaControlsView)
|
||||
}
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
mScreenOffAnimationController =
|
||||
Dependency.get(ScreenOffAnimationController.class);
|
||||
updateSplitNotificationShade();
|
||||
mSectionsManager.initialize(this, LayoutInflater.from(context));
|
||||
mSectionsManager.initialize(this);
|
||||
mSections = mSectionsManager.createSectionsForBuckets();
|
||||
|
||||
mAmbientState = Dependency.get(AmbientState.class);
|
||||
@@ -665,7 +665,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
inflateFooterView();
|
||||
inflateEmptyShadeView();
|
||||
updateFooter();
|
||||
mSectionsManager.reinflateViews(LayoutInflater.from(mContext));
|
||||
mSectionsManager.reinflateViews();
|
||||
}
|
||||
|
||||
public void setIsRemoteInputActive(boolean isActive) {
|
||||
@@ -2228,7 +2228,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
height += viewHeight;
|
||||
|
||||
numShownItems++;
|
||||
if (viewHeight > 0 || !(expandableView instanceof MediaHeaderView)) {
|
||||
if (viewHeight > 0 || !(expandableView instanceof MediaContainerView)) {
|
||||
// Only count the media as a notification if it has a positive height.
|
||||
numShownNotifs++;
|
||||
}
|
||||
@@ -3202,7 +3202,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
ignoreChildren = false;
|
||||
}
|
||||
childWasSwipedOut |= isFullySwipedOut(row);
|
||||
} else if (child instanceof MediaHeaderView) {
|
||||
} else if (child instanceof MediaContainerView) {
|
||||
childWasSwipedOut = true;
|
||||
}
|
||||
if (!childWasSwipedOut) {
|
||||
|
||||
@@ -1503,7 +1503,7 @@ public class NotificationStackScrollLayoutController {
|
||||
* from the keyguard host to the quick settings one.
|
||||
*/
|
||||
public int getFullShadeTransitionInset() {
|
||||
MediaHeaderView view = mKeyguardMediaController.getSinglePaneContainer();
|
||||
MediaContainerView view = mKeyguardMediaController.getSinglePaneContainer();
|
||||
if (view == null || view.getHeight() == 0
|
||||
|| mStatusBarStateController.getState() != KEYGUARD) {
|
||||
return 0;
|
||||
|
||||
@@ -183,7 +183,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||
import com.android.systemui.statusbar.notification.stack.AmbientState;
|
||||
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.notification.stack.MediaHeaderView;
|
||||
import com.android.systemui.statusbar.notification.stack.MediaContainerView;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
|
||||
@@ -1581,7 +1581,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
if (row.isRemoved()) {
|
||||
continue;
|
||||
}
|
||||
} else if (child instanceof MediaHeaderView) {
|
||||
} else if (child instanceof MediaContainerView) {
|
||||
if (child.getVisibility() == GONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||
import com.android.systemui.statusbar.StatusBarState
|
||||
import com.android.systemui.statusbar.SysuiStatusBarStateController
|
||||
import com.android.systemui.statusbar.notification.stack.MediaHeaderView
|
||||
import com.android.systemui.statusbar.notification.stack.MediaContainerView
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import com.android.systemui.util.animation.UniqueObjectHostView
|
||||
@@ -57,7 +57,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
@JvmField @Rule
|
||||
val mockito = MockitoJUnit.rule()
|
||||
|
||||
private val mediaHeaderView: MediaHeaderView = MediaHeaderView(context, null)
|
||||
private val mediaContainerView: MediaContainerView = MediaContainerView(context, null)
|
||||
private val hostView = UniqueObjectHostView(context)
|
||||
private lateinit var keyguardMediaController: KeyguardMediaController
|
||||
|
||||
@@ -78,7 +78,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
context,
|
||||
configurationController
|
||||
)
|
||||
keyguardMediaController.attachSinglePaneContainer(mediaHeaderView)
|
||||
keyguardMediaController.attachSinglePaneContainer(mediaContainerView)
|
||||
keyguardMediaController.useSplitShade = false
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
|
||||
keyguardMediaController.refreshMediaPosition()
|
||||
|
||||
assertThat(mediaHeaderView.visibility).isEqualTo(GONE)
|
||||
assertThat(mediaContainerView.visibility).isEqualTo(GONE)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,7 +102,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
private fun testStateVisibility(state: Int, visibility: Int) {
|
||||
whenever(statusBarStateController.state).thenReturn(state)
|
||||
keyguardMediaController.refreshMediaPosition()
|
||||
assertThat(mediaHeaderView.visibility).isEqualTo(visibility)
|
||||
assertThat(mediaContainerView.visibility).isEqualTo(visibility)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,7 +112,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
|
||||
keyguardMediaController.refreshMediaPosition()
|
||||
|
||||
assertThat(mediaHeaderView.visibility).isEqualTo(GONE)
|
||||
assertThat(mediaContainerView.visibility).isEqualTo(GONE)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -130,7 +130,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
keyguardMediaController.attachSplitShadeContainer(splitShadeContainer)
|
||||
|
||||
assertThat(splitShadeContainer.visibility).isEqualTo(GONE)
|
||||
assertThat(mediaHeaderView.visibility).isEqualTo(VISIBLE)
|
||||
assertThat(mediaContainerView.visibility).isEqualTo(VISIBLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,6 +149,6 @@ class KeyguardMediaControllerTest : SysuiTestCase() {
|
||||
keyguardMediaController.attachSplitShadeContainer(splitShadeContainer)
|
||||
|
||||
assertTrue("HostView wasn't attached to the single pane container",
|
||||
mediaHeaderView.childCount == 1)
|
||||
mediaContainerView.childCount == 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.collection.render
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||
@@ -31,18 +32,18 @@ import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
|
||||
import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
|
||||
import com.android.systemui.statusbar.notification.stack.PriorityBucket
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@SmallTest
|
||||
class NodeSpecBuilderTest : SysuiTestCase() {
|
||||
|
||||
@Mock
|
||||
private lateinit var viewBarn: NotifViewBarn
|
||||
private val mediaContainerController: MediaContainerController = mock()
|
||||
private val sectionsFeatureManager: NotificationSectionsFeatureManager = mock()
|
||||
private val viewBarn: NotifViewBarn = mock()
|
||||
|
||||
private var rootController: NodeController = buildFakeController("rootController")
|
||||
private var headerController0: NodeController = buildFakeController("header0")
|
||||
@@ -66,13 +67,12 @@ class NodeSpecBuilderTest : SysuiTestCase() {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
`when`(viewBarn.requireNodeController(any())).thenAnswer {
|
||||
whenever(mediaContainerController.mediaContainerView).thenReturn(mock())
|
||||
whenever(viewBarn.requireNodeController(any())).thenAnswer {
|
||||
fakeViewBarn.getViewByEntry(it.getArgument(0))
|
||||
}
|
||||
|
||||
specBuilder = NodeSpecBuilder(viewBarn)
|
||||
specBuilder = NodeSpecBuilder(mediaContainerController, sectionsFeatureManager, viewBarn)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,6 +108,30 @@ class NodeSpecBuilderTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testSimpleMapping() {
|
||||
checkOutput(
|
||||
// GIVEN a simple flat list of notifications all in the same headerless section
|
||||
listOf(
|
||||
notif(0, section0NoHeader),
|
||||
notif(1, section0NoHeader),
|
||||
notif(2, section0NoHeader),
|
||||
notif(3, section0NoHeader)
|
||||
),
|
||||
|
||||
// THEN we output a similarly simple flag list of nodes
|
||||
tree(
|
||||
notifNode(0),
|
||||
notifNode(1),
|
||||
notifNode(2),
|
||||
notifNode(3)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSimpleMappingWithMedia() {
|
||||
// WHEN media controls are enabled
|
||||
whenever(sectionsFeatureManager.isMediaControlsEnabled()).thenReturn(true)
|
||||
|
||||
checkOutput(
|
||||
// GIVEN a simple flat list of notifications all in the same headerless section
|
||||
listOf(
|
||||
@@ -117,8 +141,9 @@ class NodeSpecBuilderTest : SysuiTestCase() {
|
||||
notif(3, section0NoHeader)
|
||||
),
|
||||
|
||||
// THEN we output a similarly simple flag list of nodes
|
||||
// THEN we output a similarly simple flag list of nodes, with media at the top
|
||||
tree(
|
||||
node(mediaContainerController),
|
||||
notifNode(0),
|
||||
notifNode(1),
|
||||
notifNode(2),
|
||||
@@ -333,7 +358,7 @@ private class FakeViewBarn {
|
||||
|
||||
private fun buildFakeController(name: String): NodeController {
|
||||
val controller = Mockito.mock(NodeController::class.java)
|
||||
`when`(controller.nodeLabel).thenReturn(name)
|
||||
whenever(controller.nodeLabel).thenReturn(name)
|
||||
return controller
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import static org.mockito.Mockito.when;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@@ -54,6 +53,7 @@ import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.render.MediaContainerController;
|
||||
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
@@ -87,6 +87,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
||||
@Mock private NotificationRowComponent mNotificationRowComponent;
|
||||
@Mock private ActivatableNotificationViewController mActivatableNotificationViewController;
|
||||
@Mock private NotificationSectionsLogger mLogger;
|
||||
@Mock private MediaContainerController mMediaContainerController;
|
||||
@Mock private SectionHeaderController mIncomingHeaderController;
|
||||
@Mock private SectionHeaderController mPeopleHeaderController;
|
||||
@Mock private SectionHeaderController mAlertingHeaderController;
|
||||
@@ -114,6 +115,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
||||
});
|
||||
when(mNotificationRowComponent.getActivatableNotificationViewController())
|
||||
.thenReturn(mActivatableNotificationViewController);
|
||||
when(mMediaContainerController.getMediaContainerView())
|
||||
.thenReturn(mock(MediaContainerView.class));
|
||||
when(mIncomingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
|
||||
when(mPeopleHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
|
||||
when(mAlertingHeaderController.getHeaderView()).thenReturn(mock(SectionHeaderView.class));
|
||||
@@ -126,6 +129,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
||||
mSectionsFeatureManager,
|
||||
mLogger,
|
||||
mNotifPipelineFlags,
|
||||
mMediaContainerController,
|
||||
mIncomingHeaderController,
|
||||
mPeopleHeaderController,
|
||||
mAlertingHeaderController,
|
||||
@@ -134,7 +138,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
||||
// Required in order for the header inflation to work properly
|
||||
when(mNssl.generateLayoutParams(any(AttributeSet.class)))
|
||||
.thenReturn(new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT));
|
||||
mSectionsManager.initialize(mNssl, LayoutInflater.from(mContext));
|
||||
mSectionsManager.initialize(mNssl);
|
||||
when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
|
||||
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
|
||||
|
||||
@@ -142,7 +146,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testDuplicateInitializeThrows() {
|
||||
mSectionsManager.initialize(mNssl, LayoutInflater.from(mContext));
|
||||
mSectionsManager.initialize(mNssl);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user