Merge "New Pipeline: Bring in a couple missing features"
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A class which is used to classify the sections.
|
||||
* NOTE: This class exists to avoid putting metadata like "isMinimized" on the NotifSection
|
||||
*/
|
||||
@SysUISingleton
|
||||
class SectionClassifier @Inject constructor() {
|
||||
private lateinit var lowPrioritySections: Set<NotifSectioner>
|
||||
|
||||
/**
|
||||
* Feed the provider the information it needs about which sections should have minimized top
|
||||
* level views, so that it can calculate the correct minimized state.
|
||||
*/
|
||||
fun setMinimizedSections(sections: Collection<NotifSectioner>) {
|
||||
lowPrioritySections = sections.toSet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given section is minimized
|
||||
*/
|
||||
fun isMinimizedSection(section: NotifSection): Boolean {
|
||||
return lowPrioritySections.contains(section.sectioner)
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ class NotifCoordinatorsImpl @Inject constructor(
|
||||
groupCountCoordinator: GroupCountCoordinator,
|
||||
mediaCoordinator: MediaCoordinator,
|
||||
remoteInputCoordinator: RemoteInputCoordinator,
|
||||
rowAppearanceCoordinator: RowAppearanceCoordinator,
|
||||
stackCoordinator: StackCoordinator,
|
||||
shadeEventCoordinator: ShadeEventCoordinator,
|
||||
smartspaceDedupingCoordinator: SmartspaceDedupingCoordinator,
|
||||
@@ -77,6 +78,7 @@ class NotifCoordinatorsImpl @Inject constructor(
|
||||
mCoordinators.add(groupCountCoordinator)
|
||||
mCoordinators.add(mediaCoordinator)
|
||||
mCoordinators.add(remoteInputCoordinator)
|
||||
mCoordinators.add(rowAppearanceCoordinator)
|
||||
mCoordinators.add(stackCoordinator)
|
||||
mCoordinators.add(shadeEventCoordinator)
|
||||
mCoordinators.add(viewConfigCoordinator)
|
||||
|
||||
@@ -20,11 +20,11 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.notification.SectionClassifier;
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
|
||||
import com.android.systemui.statusbar.notification.collection.inflation.NotifUiAdjustmentProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||
@@ -51,7 +51,7 @@ public class RankingCoordinator implements Coordinator {
|
||||
public static final boolean SHOW_ALL_SECTIONS = false;
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
private final HighPriorityProvider mHighPriorityProvider;
|
||||
private final NotifUiAdjustmentProvider mAdjustmentProvider;
|
||||
private final SectionClassifier mSectionClassifier;
|
||||
private final NodeController mSilentNodeController;
|
||||
private final SectionHeaderController mSilentHeaderController;
|
||||
private final NodeController mAlertingHeaderController;
|
||||
@@ -62,13 +62,13 @@ public class RankingCoordinator implements Coordinator {
|
||||
public RankingCoordinator(
|
||||
StatusBarStateController statusBarStateController,
|
||||
HighPriorityProvider highPriorityProvider,
|
||||
NotifUiAdjustmentProvider adjustmentProvider,
|
||||
SectionClassifier sectionClassifier,
|
||||
@AlertingHeader NodeController alertingHeaderController,
|
||||
@SilentHeader SectionHeaderController silentHeaderController,
|
||||
@SilentHeader NodeController silentNodeController) {
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mHighPriorityProvider = highPriorityProvider;
|
||||
mAdjustmentProvider = adjustmentProvider;
|
||||
mSectionClassifier = sectionClassifier;
|
||||
mAlertingHeaderController = alertingHeaderController;
|
||||
mSilentNodeController = silentNodeController;
|
||||
mSilentHeaderController = silentHeaderController;
|
||||
@@ -77,7 +77,7 @@ public class RankingCoordinator implements Coordinator {
|
||||
@Override
|
||||
public void attach(NotifPipeline pipeline) {
|
||||
mStatusBarStateController.addCallback(mStatusBarStateCallback);
|
||||
mAdjustmentProvider.setLowPrioritySections(Collections.singleton(mMinimizedNotifSectioner));
|
||||
mSectionClassifier.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
|
||||
|
||||
pipeline.addPreGroupFilter(mSuspendedFilter);
|
||||
pipeline.addPreGroupFilter(mDndVisualEffectsFilter);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.coordinator
|
||||
|
||||
import android.content.Context
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController
|
||||
import com.android.systemui.statusbar.notification.SectionClassifier
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifRowController
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A small coordinator which updates the notif rows with data related to the current shade after
|
||||
* they are fully attached.
|
||||
*/
|
||||
@CoordinatorScope
|
||||
class RowAppearanceCoordinator @Inject internal constructor(
|
||||
context: Context,
|
||||
private var mAssistantFeedbackController: AssistantFeedbackController,
|
||||
private var mSectionClassifier: SectionClassifier
|
||||
) : Coordinator {
|
||||
|
||||
private var entryToExpand: NotificationEntry? = null
|
||||
|
||||
/**
|
||||
* `true` if notifications not part of a group should by default be rendered in their
|
||||
* expanded state. If `false`, then only the first notification will be expanded if
|
||||
* possible.
|
||||
*/
|
||||
private val mAlwaysExpandNonGroupedNotification =
|
||||
context.resources.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications)
|
||||
|
||||
override fun attach(pipeline: NotifPipeline) {
|
||||
pipeline.addOnBeforeRenderListListener(::onBeforeRenderList)
|
||||
pipeline.addOnAfterRenderEntryListener(::onAfterRenderEntry)
|
||||
}
|
||||
|
||||
private fun onBeforeRenderList(list: List<ListEntry>) {
|
||||
entryToExpand = list.firstOrNull()?.representativeEntry?.takeIf { entry ->
|
||||
!mSectionClassifier.isMinimizedSection(entry.section!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onAfterRenderEntry(entry: NotificationEntry, controller: NotifRowController) {
|
||||
// If mAlwaysExpandNonGroupedNotification is false, then only expand the
|
||||
// very first notification and if it's not a child of grouped notifications.
|
||||
controller.setSystemExpanded(mAlwaysExpandNonGroupedNotification || entry == entryToExpand)
|
||||
// Show/hide the feedback icon
|
||||
controller.showFeedbackIcon(
|
||||
mAssistantFeedbackController.showFeedbackIndicator(entry),
|
||||
mAssistantFeedbackController.getFeedbackResources(entry)
|
||||
)
|
||||
// Show the "alerted" bell icon
|
||||
controller.setLastAudiblyAlertedMs(entry.lastAudiblyAlertedMs)
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@
|
||||
package com.android.systemui.statusbar.notification.collection.inflation
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.statusbar.notification.SectionClassifier
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntry
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -27,25 +27,17 @@ import javax.inject.Inject
|
||||
* to ensure that notifications are reinflated when ranking-derived information changes.
|
||||
*/
|
||||
@SysUISingleton
|
||||
open class NotifUiAdjustmentProvider @Inject constructor() {
|
||||
|
||||
private lateinit var lowPrioritySections: Set<NotifSectioner>
|
||||
|
||||
/**
|
||||
* Feed the provider the information it needs about which sections should have minimized top
|
||||
* level views, so that it can calculate the correct minimized value in the adjustment.
|
||||
*/
|
||||
fun setLowPrioritySections(sections: Collection<NotifSectioner>) {
|
||||
lowPrioritySections = sections.toSet()
|
||||
}
|
||||
open class NotifUiAdjustmentProvider @Inject constructor(
|
||||
private val sectionClassifier: SectionClassifier
|
||||
) {
|
||||
|
||||
private fun isEntryMinimized(entry: NotificationEntry): Boolean {
|
||||
val section = entry.section ?: error("Entry must have a section to determine if minimized")
|
||||
val parent = entry.parent ?: error("Entry must have a parent to determine if minimized")
|
||||
val isLowPrioritySection = lowPrioritySections.contains(section.sectioner)
|
||||
val isMinimizedSection = sectionClassifier.isMinimizedSection(section)
|
||||
val isTopLevelEntry = parent == GroupEntry.ROOT_ENTRY
|
||||
val isGroupSummary = parent.summary == entry
|
||||
return isLowPrioritySection && (isTopLevelEntry || isGroupSummary)
|
||||
return isMinimizedSection && (isTopLevelEntry || isGroupSummary)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,5 +16,27 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.collection.render
|
||||
|
||||
import android.util.Pair
|
||||
|
||||
/** A view controller for a notification row */
|
||||
interface NotifRowController
|
||||
interface NotifRowController {
|
||||
/**
|
||||
* This tells the row what the 'default expanded' state should be. Once a user expands or
|
||||
* contracts a row, that will set the user expanded state, which takes precedence, but
|
||||
* collapsing the shade and re-opening it will clear the user expanded state. This allows for
|
||||
* nice auto expansion of the next notification as users dismiss the top notification.
|
||||
*/
|
||||
fun setSystemExpanded(systemExpanded: Boolean)
|
||||
|
||||
/**
|
||||
* Sets the timestamp that the notification was last audibly alerted, which the row uses to
|
||||
* show a bell icon in the header which indicates to the user which notification made a noise.
|
||||
*/
|
||||
fun setLastAudiblyAlertedMs(lastAudiblyAlertedMs: Long)
|
||||
|
||||
/**
|
||||
* Sets both whether to show a feedback indicator and which resources to use for the drawable
|
||||
* and content description.
|
||||
*/
|
||||
fun showFeedbackIcon(showFeedbackIndicator: Boolean, feedbackResources: Pair<Int, Int>?)
|
||||
}
|
||||
|
||||
@@ -815,6 +815,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
mChildrenContainer.setUntruncatedChildCount(childCount);
|
||||
}
|
||||
|
||||
/** Called after children have been attached to set the expansion states */
|
||||
public void resetChildSystemExpandedStates() {
|
||||
if (isSummaryWithChildren()) {
|
||||
mChildrenContainer.updateExpansionStates();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child notification to this view.
|
||||
*
|
||||
@@ -2342,6 +2349,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
onExpansionChanged(false /* userAction */, wasExpanded);
|
||||
if (mIsSummaryWithChildren) {
|
||||
mChildrenContainer.updateGroupOverflow();
|
||||
resetChildSystemExpandedStates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENAB
|
||||
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
@@ -279,4 +280,19 @@ public class ExpandableNotificationRowController implements NotifViewController
|
||||
Log.w(TAG, "Called setUntruncatedChildCount(" + childCount + ") on a leaf row");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSystemExpanded(boolean systemExpanded) {
|
||||
mView.setSystemExpanded(systemExpanded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastAudiblyAlertedMs(long lastAudiblyAlertedMs) {
|
||||
mView.setLastAudiblyAlertedMs(lastAudiblyAlertedMs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showFeedbackIcon(boolean show, Pair<Integer, Integer> feedbackResources) {
|
||||
mView.showFeedbackIcon(show, feedbackResources);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +478,8 @@ public class NotificationChildrenContainer extends ViewGroup
|
||||
return result;
|
||||
}
|
||||
|
||||
private void updateExpansionStates() {
|
||||
/** To be called any time the rows have been updated */
|
||||
public void updateExpansionStates() {
|
||||
if (mChildrenExpanded || mUserLocked) {
|
||||
// we don't modify it the group is expanded or if we are expanding it
|
||||
return;
|
||||
|
||||
@@ -40,6 +40,7 @@ import androidx.test.filters.SmallTest;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.RankingBuilder;
|
||||
import com.android.systemui.statusbar.notification.SectionClassifier;
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||
@@ -92,7 +93,9 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
||||
@Mock private NotifPipeline mNotifPipeline;
|
||||
@Mock private IStatusBarService mService;
|
||||
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
|
||||
private final TestableAdjustmentProvider mAdjustmentProvider = new TestableAdjustmentProvider();
|
||||
private final SectionClassifier mSectionClassifier = new SectionClassifier();
|
||||
private final NotifUiAdjustmentProvider mAdjustmentProvider =
|
||||
new NotifUiAdjustmentProvider(mSectionClassifier);
|
||||
|
||||
@NonNull
|
||||
private NotificationEntryBuilder getNotificationEntryBuilder() {
|
||||
@@ -107,7 +110,7 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
||||
mInflationError = new Exception(TEST_MESSAGE);
|
||||
mErrorManager = new NotifInflationErrorManager();
|
||||
when(mNotifSection.getSectioner()).thenReturn(mNotifSectioner);
|
||||
mAdjustmentProvider.setSectionIsLowPriority(false);
|
||||
setSectionIsLowPriority(false);
|
||||
|
||||
PreparationCoordinator coordinator = new PreparationCoordinator(
|
||||
mock(PreparationCoordinatorLogger.class),
|
||||
@@ -222,7 +225,7 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
||||
mNotifInflater.invokeInflateCallbackForEntry(mEntry);
|
||||
|
||||
// WHEN notification moves to a min priority section
|
||||
mAdjustmentProvider.setSectionIsLowPriority(true);
|
||||
setSectionIsLowPriority(true);
|
||||
mBeforeFilterListener.onBeforeFinalizeFilter(List.of(mEntry));
|
||||
|
||||
// THEN we rebind it
|
||||
@@ -236,7 +239,7 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testMinimizedEntryMovedIntoGroupWillRebindViews() {
|
||||
// GIVEN an inflated, minimized notification
|
||||
mAdjustmentProvider.setSectionIsLowPriority(true);
|
||||
setSectionIsLowPriority(true);
|
||||
mCollectionListener.onEntryAdded(mEntry);
|
||||
mBeforeFilterListener.onBeforeFinalizeFilter(List.of(mEntry));
|
||||
verify(mNotifInflater).inflateViews(eq(mEntry), mParamsCaptor.capture(), any());
|
||||
@@ -471,11 +474,9 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
|
||||
private static final int TEST_CHILD_BIND_CUTOFF = 9;
|
||||
private static final int TEST_MAX_GROUP_DELAY = 100;
|
||||
|
||||
private class TestableAdjustmentProvider extends NotifUiAdjustmentProvider {
|
||||
private void setSectionIsLowPriority(boolean lowPriority) {
|
||||
setLowPrioritySections(lowPriority
|
||||
? Collections.singleton(mNotifSection.getSectioner())
|
||||
: Collections.emptyList());
|
||||
}
|
||||
private void setSectionIsLowPriority(boolean minimized) {
|
||||
mSectionClassifier.setMinimizedSections(minimized
|
||||
? Collections.singleton(mNotifSection.getSectioner())
|
||||
: Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICAT
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -39,11 +40,11 @@ import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.RankingBuilder;
|
||||
import com.android.systemui.statusbar.SbnBuilder;
|
||||
import com.android.systemui.statusbar.notification.SectionClassifier;
|
||||
import com.android.systemui.statusbar.notification.collection.ListEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
|
||||
import com.android.systemui.statusbar.notification.collection.inflation.NotifUiAdjustmentProvider;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
|
||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||
@@ -67,7 +68,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
||||
|
||||
@Mock private StatusBarStateController mStatusBarStateController;
|
||||
@Mock private HighPriorityProvider mHighPriorityProvider;
|
||||
@Mock private NotifUiAdjustmentProvider mAdjustmentProvider;
|
||||
@Mock private SectionClassifier mSectionClassifier;
|
||||
@Mock private NotifPipeline mNotifPipeline;
|
||||
@Mock private NodeController mAlertingHeaderController;
|
||||
@Mock private NodeController mSilentNodeController;
|
||||
@@ -91,7 +92,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
||||
mRankingCoordinator = new RankingCoordinator(
|
||||
mStatusBarStateController,
|
||||
mHighPriorityProvider,
|
||||
mAdjustmentProvider,
|
||||
mSectionClassifier,
|
||||
mAlertingHeaderController,
|
||||
mSilentHeaderController,
|
||||
mSilentNodeController);
|
||||
@@ -99,6 +100,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
|
||||
mEntry.setRanking(getRankingForUnfilteredNotif().build());
|
||||
|
||||
mRankingCoordinator.attach(mNotifPipeline);
|
||||
verify(mSectionClassifier).setMinimizedSections(any());
|
||||
verify(mNotifPipeline, times(2)).addPreGroupFilter(mNotifFilterCaptor.capture());
|
||||
mCapturedSuspendedFilter = mNotifFilterCaptor.getAllValues().get(0);
|
||||
mCapturedDozingFilter = mNotifFilterCaptor.getAllValues().get(1);
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.coordinator
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper.RunWithLooper
|
||||
import android.util.Pair
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.statusbar.notification.AssistantFeedbackController
|
||||
import com.android.systemui.statusbar.notification.SectionClassifier
|
||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
|
||||
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifRowController
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations.initMocks
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@RunWithLooper
|
||||
class RowAppearanceCoordinatorTest : SysuiTestCase() {
|
||||
private lateinit var coordinator: RowAppearanceCoordinator
|
||||
private lateinit var beforeRenderListListener: OnBeforeRenderListListener
|
||||
private lateinit var afterRenderEntryListener: OnAfterRenderEntryListener
|
||||
|
||||
private lateinit var entry1: NotificationEntry
|
||||
private lateinit var entry2: NotificationEntry
|
||||
|
||||
@Mock private lateinit var pipeline: NotifPipeline
|
||||
@Mock private lateinit var assistantFeedbackController: AssistantFeedbackController
|
||||
@Mock private lateinit var sectionClassifier: SectionClassifier
|
||||
|
||||
@Mock private lateinit var section1: NotifSection
|
||||
@Mock private lateinit var section2: NotifSection
|
||||
@Mock private lateinit var controller1: NotifRowController
|
||||
@Mock private lateinit var controller2: NotifRowController
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
initMocks(this)
|
||||
coordinator = RowAppearanceCoordinator(
|
||||
mContext,
|
||||
assistantFeedbackController,
|
||||
sectionClassifier
|
||||
)
|
||||
coordinator.attach(pipeline)
|
||||
beforeRenderListListener = withArgCaptor {
|
||||
verify(pipeline).addOnBeforeRenderListListener(capture())
|
||||
}
|
||||
afterRenderEntryListener = withArgCaptor {
|
||||
verify(pipeline).addOnAfterRenderEntryListener(capture())
|
||||
}
|
||||
whenever(assistantFeedbackController.showFeedbackIndicator(any())).thenReturn(true)
|
||||
whenever(assistantFeedbackController.getFeedbackResources(any())).thenReturn(Pair(1, 2))
|
||||
entry1 = NotificationEntryBuilder().setSection(section1).setLastAudiblyAlertedMs(17).build()
|
||||
entry2 = NotificationEntryBuilder().setSection(section2).build()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetSystemExpandedOnlyOnFirst() {
|
||||
whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
|
||||
whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
|
||||
beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
|
||||
afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
|
||||
verify(controller1).setSystemExpanded(eq(true))
|
||||
afterRenderEntryListener.onAfterRenderEntry(entry2, controller2)
|
||||
verify(controller2).setSystemExpanded(eq(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetSystemExpandedNeverIfMinimized() {
|
||||
whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
|
||||
whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
|
||||
beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
|
||||
afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
|
||||
verify(controller1).setSystemExpanded(eq(false))
|
||||
afterRenderEntryListener.onAfterRenderEntry(entry2, controller2)
|
||||
verify(controller2).setSystemExpanded(eq(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetLastAudiblyAlerted() {
|
||||
afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
|
||||
verify(controller1).setLastAudiblyAlertedMs(eq(17.toLong()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testShowFeedbackIcon() {
|
||||
afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
|
||||
verify(controller1).showFeedbackIcon(eq(true), eq(Pair(1, 2)))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user