Merge "Add unlock to see more messaging to locked shade" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0b72c62716
@@ -21,12 +21,29 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
>
|
>
|
||||||
<TextView
|
<LinearLayout android:orientation="vertical"
|
||||||
android:id="@+id/no_notifications"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="64dp"
|
android:layout_gravity="center"
|
||||||
android:textAppearance="?android:attr/textAppearanceButton"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/empty_shade_text"/>
|
>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/no_notifications"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="64dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceButton"
|
||||||
|
android:text="@string/empty_shade_text"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/no_notifications_footer"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:gravity="center"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceButton"
|
||||||
|
android:text="@string/unlock_to_see_notif_text"/>
|
||||||
|
</LinearLayout>
|
||||||
</com.android.systemui.statusbar.EmptyShadeView>
|
</com.android.systemui.statusbar.EmptyShadeView>
|
||||||
|
|||||||
@@ -403,6 +403,8 @@
|
|||||||
(quick_qs_offset_height (60dp) - ongoing_appops_chip_height (24dp) ) / 2 -->
|
(quick_qs_offset_height (60dp) - ongoing_appops_chip_height (24dp) ) / 2 -->
|
||||||
<dimen name="notifications_top_padding_split_shade">18dp</dimen>
|
<dimen name="notifications_top_padding_split_shade">18dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="notifications_unseen_footer_icon_size">16dp</dimen>
|
||||||
|
|
||||||
<!-- Height of the status bar header bar when on Keyguard -->
|
<!-- Height of the status bar header bar when on Keyguard -->
|
||||||
<dimen name="status_bar_header_height_keyguard">40dp</dimen>
|
<dimen name="status_bar_header_height_keyguard">40dp</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -1049,6 +1049,12 @@
|
|||||||
<!-- Text which is shown in the notification shade when there are no notifications. [CHAR LIMIT=30] -->
|
<!-- Text which is shown in the notification shade when there are no notifications. [CHAR LIMIT=30] -->
|
||||||
<string name="empty_shade_text">No notifications</string>
|
<string name="empty_shade_text">No notifications</string>
|
||||||
|
|
||||||
|
<!-- Text which is shown in the expanded notification shade when there are currently no notifications visible that the user hasn't already seen. [CHAR LIMIT=30] -->
|
||||||
|
<string name="no_unseen_notif_text">No new notifications</string>
|
||||||
|
|
||||||
|
<!-- Text which is shown in the locked notification shade when there are currently no notifications, but if the user were to unlock, notifications would appear. [CHAR LIMIT=40] -->
|
||||||
|
<string name="unlock_to_see_notif_text">Unlock to see older notifications</string>
|
||||||
|
|
||||||
<!-- Disclosure at the bottom of Quick Settings that indicates that parental controls are enabled. [CHAR LIMIT=100] -->
|
<!-- Disclosure at the bottom of Quick Settings that indicates that parental controls are enabled. [CHAR LIMIT=100] -->
|
||||||
<string name="quick_settings_disclosure_parental_controls">This device is managed by your parent</string>
|
<string name="quick_settings_disclosure_parental_controls">This device is managed by your parent</string>
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
package com.android.systemui.statusbar;
|
package com.android.systemui.statusbar;
|
||||||
|
|
||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
|
import android.annotation.DrawableRes;
|
||||||
import android.annotation.StringRes;
|
import android.annotation.StringRes;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -33,16 +36,30 @@ import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
|
|||||||
public class EmptyShadeView extends StackScrollerDecorView {
|
public class EmptyShadeView extends StackScrollerDecorView {
|
||||||
|
|
||||||
private TextView mEmptyText;
|
private TextView mEmptyText;
|
||||||
|
private TextView mEmptyFooterText;
|
||||||
|
|
||||||
private @StringRes int mText = R.string.empty_shade_text;
|
private @StringRes int mText = R.string.empty_shade_text;
|
||||||
|
|
||||||
|
private @DrawableRes int mFooterIcon = R.drawable.ic_friction_lock_closed;
|
||||||
|
private @StringRes int mFooterText = R.string.unlock_to_see_notif_text;
|
||||||
|
private @Visibility int mFooterVisibility = View.GONE;
|
||||||
|
private int mSize;
|
||||||
|
|
||||||
public EmptyShadeView(Context context, AttributeSet attrs) {
|
public EmptyShadeView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
|
mSize = getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.notifications_unseen_footer_icon_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onConfigurationChanged(Configuration newConfig) {
|
protected void onConfigurationChanged(Configuration newConfig) {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
|
mSize = getResources().getDimensionPixelSize(
|
||||||
|
R.dimen.notifications_unseen_footer_icon_size);
|
||||||
mEmptyText.setText(mText);
|
mEmptyText.setText(mText);
|
||||||
|
mEmptyFooterText.setVisibility(mFooterVisibility);
|
||||||
|
setFooterText(mFooterText);
|
||||||
|
setFooterIcon(mFooterIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -52,11 +69,13 @@ public class EmptyShadeView extends StackScrollerDecorView {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected View findSecondaryView() {
|
protected View findSecondaryView() {
|
||||||
return null;
|
return findViewById(R.id.no_notifications_footer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextColor(@ColorInt int color) {
|
public void setTextColor(@ColorInt int color) {
|
||||||
mEmptyText.setTextColor(color);
|
mEmptyText.setTextColor(color);
|
||||||
|
mEmptyFooterText.setTextColor(color);
|
||||||
|
mEmptyFooterText.setCompoundDrawableTintList(ColorStateList.valueOf(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(@StringRes int text) {
|
public void setText(@StringRes int text) {
|
||||||
@@ -64,14 +83,53 @@ public class EmptyShadeView extends StackScrollerDecorView {
|
|||||||
mEmptyText.setText(mText);
|
mEmptyText.setText(mText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFooterVisibility(@Visibility int visibility) {
|
||||||
|
mFooterVisibility = visibility;
|
||||||
|
setSecondaryVisible(visibility == View.VISIBLE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFooterText(@StringRes int text) {
|
||||||
|
mFooterText = text;
|
||||||
|
if (text != 0) {
|
||||||
|
mEmptyFooterText.setText(mFooterText);
|
||||||
|
} else {
|
||||||
|
mEmptyFooterText.setText(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFooterIcon(@DrawableRes int icon) {
|
||||||
|
mFooterIcon = icon;
|
||||||
|
Drawable drawable;
|
||||||
|
if (icon == 0) {
|
||||||
|
drawable = null;
|
||||||
|
} else {
|
||||||
|
drawable = getResources().getDrawable(icon);
|
||||||
|
drawable.setBounds(0, 0, mSize, mSize);
|
||||||
|
}
|
||||||
|
mEmptyFooterText.setCompoundDrawablesRelative(drawable, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@StringRes
|
||||||
public int getTextResource() {
|
public int getTextResource() {
|
||||||
return mText;
|
return mText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@StringRes
|
||||||
|
public int getFooterTextResource() {
|
||||||
|
return mFooterText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DrawableRes
|
||||||
|
public int getFooterIconResource() {
|
||||||
|
return mFooterIcon;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
mEmptyText = (TextView) findContentView();
|
mEmptyText = (TextView) findContentView();
|
||||||
|
mEmptyFooterText = (TextView) findSecondaryView();
|
||||||
|
mEmptyFooterText.setCompoundDrawableTintList(mEmptyFooterText.getTextColors());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
|
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
|
||||||
|
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
|
||||||
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
|
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
@@ -49,6 +50,7 @@ constructor(
|
|||||||
private val notifPipelineFlags: NotifPipelineFlags,
|
private val notifPipelineFlags: NotifPipelineFlags,
|
||||||
@Application private val scope: CoroutineScope,
|
@Application private val scope: CoroutineScope,
|
||||||
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
|
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
|
||||||
|
private val seenNotifsProvider: SeenNotificationsProviderImpl,
|
||||||
private val statusBarStateController: StatusBarStateController,
|
private val statusBarStateController: StatusBarStateController,
|
||||||
) : Coordinator {
|
) : Coordinator {
|
||||||
|
|
||||||
@@ -105,6 +107,9 @@ constructor(
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
internal val unseenNotifFilter =
|
internal val unseenNotifFilter =
|
||||||
object : NotifFilter("$TAG-unseen") {
|
object : NotifFilter("$TAG-unseen") {
|
||||||
|
|
||||||
|
var hasFilteredAnyNotifs = false
|
||||||
|
|
||||||
override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean =
|
override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean =
|
||||||
when {
|
when {
|
||||||
// Don't apply filter if the keyguard isn't currently showing
|
// Don't apply filter if the keyguard isn't currently showing
|
||||||
@@ -115,7 +120,12 @@ constructor(
|
|||||||
// - summary will be pruned if necessary, depending on if children are filtered
|
// - summary will be pruned if necessary, depending on if children are filtered
|
||||||
entry.parent?.summary == entry -> false
|
entry.parent?.summary == entry -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}.also { hasFiltered -> hasFilteredAnyNotifs = hasFilteredAnyNotifs || hasFiltered }
|
||||||
|
|
||||||
|
override fun onCleanup() {
|
||||||
|
seenNotifsProvider.hasFilteredOutSeenNotifications = hasFilteredAnyNotifs
|
||||||
|
hasFilteredAnyNotifs = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val notifFilter: NotifFilter =
|
private val notifFilter: NotifFilter =
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.notification.collection.provider
|
||||||
|
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import dagger.Binds
|
||||||
|
import dagger.Module
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/** Keeps track of whether "seen" notification content has been filtered out of the shade. */
|
||||||
|
interface SeenNotificationsProvider {
|
||||||
|
/** Are any already-seen notifications currently filtered out of the shade? */
|
||||||
|
val hasFilteredOutSeenNotifications: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
@Module
|
||||||
|
interface SeenNotificationsProviderModule {
|
||||||
|
@Binds
|
||||||
|
fun bindSeenNotificationsProvider(
|
||||||
|
impl: SeenNotificationsProviderImpl
|
||||||
|
): SeenNotificationsProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
@SysUISingleton
|
||||||
|
class SeenNotificationsProviderImpl @Inject constructor() : SeenNotificationsProvider {
|
||||||
|
override var hasFilteredOutSeenNotifications: Boolean = false
|
||||||
|
}
|
||||||
@@ -52,6 +52,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.OnUserIn
|
|||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl;
|
import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderModule;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl;
|
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl;
|
||||||
@@ -96,6 +97,7 @@ import dagger.Provides;
|
|||||||
@Module(includes = {
|
@Module(includes = {
|
||||||
CoordinatorsModule.class,
|
CoordinatorsModule.class,
|
||||||
KeyguardNotificationVisibilityProviderModule.class,
|
KeyguardNotificationVisibilityProviderModule.class,
|
||||||
|
SeenNotificationsProviderModule.class,
|
||||||
ShadeEventsModule.class,
|
ShadeEventsModule.class,
|
||||||
NotifPipelineChoreographerModule.class,
|
NotifPipelineChoreographerModule.class,
|
||||||
NotificationSectionHeadersModule.class,
|
NotificationSectionHeadersModule.class,
|
||||||
|
|||||||
@@ -32,10 +32,12 @@ import android.animation.AnimatorListenerAdapter;
|
|||||||
import android.animation.TimeAnimator;
|
import android.animation.TimeAnimator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.ColorInt;
|
import android.annotation.ColorInt;
|
||||||
|
import android.annotation.DrawableRes;
|
||||||
import android.annotation.FloatRange;
|
import android.annotation.FloatRange;
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.StringRes;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@@ -4556,7 +4558,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
void setEmptyShadeView(EmptyShadeView emptyShadeView) {
|
public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
|
||||||
int index = -1;
|
int index = -1;
|
||||||
if (mEmptyShadeView != null) {
|
if (mEmptyShadeView != null) {
|
||||||
index = indexOfChild(mEmptyShadeView);
|
index = indexOfChild(mEmptyShadeView);
|
||||||
@@ -4567,15 +4569,43 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
|
void updateEmptyShadeView(
|
||||||
|
boolean visible, boolean areNotificationsHiddenInShade, boolean areSeenNotifsFiltered) {
|
||||||
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
|
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
|
||||||
|
|
||||||
|
if (areNotificationsHiddenInShade) {
|
||||||
|
updateEmptyShadeView(R.string.dnd_suppressing_shade_text, 0, 0);
|
||||||
|
} else if (areSeenNotifsFiltered) {
|
||||||
|
updateEmptyShadeView(
|
||||||
|
R.string.no_unseen_notif_text,
|
||||||
|
R.string.unlock_to_see_notif_text,
|
||||||
|
R.drawable.ic_friction_lock_closed);
|
||||||
|
} else {
|
||||||
|
updateEmptyShadeView(R.string.empty_shade_text, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateEmptyShadeView(
|
||||||
|
@StringRes int newTextRes,
|
||||||
|
@StringRes int newFooterTextRes,
|
||||||
|
@DrawableRes int newFooterIconRes) {
|
||||||
int oldTextRes = mEmptyShadeView.getTextResource();
|
int oldTextRes = mEmptyShadeView.getTextResource();
|
||||||
int newTextRes = areNotificationsHiddenInShade
|
|
||||||
? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
|
|
||||||
if (oldTextRes != newTextRes) {
|
if (oldTextRes != newTextRes) {
|
||||||
mEmptyShadeView.setText(newTextRes);
|
mEmptyShadeView.setText(newTextRes);
|
||||||
}
|
}
|
||||||
|
int oldFooterTextRes = mEmptyShadeView.getFooterTextResource();
|
||||||
|
if (oldFooterTextRes != newFooterTextRes) {
|
||||||
|
mEmptyShadeView.setFooterText(newFooterTextRes);
|
||||||
|
}
|
||||||
|
int oldFooterIconRes = mEmptyShadeView.getFooterIconResource();
|
||||||
|
if (oldFooterIconRes != newFooterIconRes) {
|
||||||
|
mEmptyShadeView.setFooterIcon(newFooterIconRes);
|
||||||
|
}
|
||||||
|
if (newFooterIconRes != 0 || newFooterTextRes != 0) {
|
||||||
|
mEmptyShadeView.setFooterVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mEmptyShadeView.setFooterVisibility(View.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmptyShadeViewVisible() {
|
public boolean isEmptyShadeViewVisible() {
|
||||||
@@ -5348,9 +5378,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
|
|
||||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||||
private void inflateEmptyShadeView() {
|
private void inflateEmptyShadeView() {
|
||||||
|
EmptyShadeView oldView = mEmptyShadeView;
|
||||||
EmptyShadeView view = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
|
EmptyShadeView view = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
|
||||||
R.layout.status_bar_no_notifications, this, false);
|
R.layout.status_bar_no_notifications, this, false);
|
||||||
view.setText(R.string.empty_shade_text);
|
|
||||||
view.setOnClickListener(v -> {
|
view.setOnClickListener(v -> {
|
||||||
final boolean showHistory = mController.isHistoryEnabled();
|
final boolean showHistory = mController.isHistoryEnabled();
|
||||||
Intent intent = showHistory
|
Intent intent = showHistory
|
||||||
@@ -5359,6 +5389,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
|||||||
mCentralSurfaces.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
mCentralSurfaces.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||||
});
|
});
|
||||||
setEmptyShadeView(view);
|
setEmptyShadeView(view);
|
||||||
|
updateEmptyShadeView(
|
||||||
|
oldView == null ? R.string.empty_shade_text : oldView.getTextResource(),
|
||||||
|
oldView == null ? 0 : oldView.getFooterTextResource(),
|
||||||
|
oldView == null ? 0 : oldView.getFooterIconResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ import com.android.systemui.statusbar.StatusBarState;
|
|||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||||
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
|
||||||
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
@@ -89,6 +90,7 @@ import com.android.systemui.statusbar.notification.collection.PipelineDumpable;
|
|||||||
import com.android.systemui.statusbar.notification.collection.PipelineDumper;
|
import com.android.systemui.statusbar.notification.collection.PipelineDumper;
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
|
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
|
||||||
@@ -174,6 +176,8 @@ public class NotificationStackScrollLayoutController {
|
|||||||
private final StackStateLogger mStackStateLogger;
|
private final StackStateLogger mStackStateLogger;
|
||||||
private final NotificationStackScrollLogger mLogger;
|
private final NotificationStackScrollLogger mLogger;
|
||||||
private final GroupExpansionManager mGroupExpansionManager;
|
private final GroupExpansionManager mGroupExpansionManager;
|
||||||
|
private final NotifPipelineFlags mNotifPipelineFlags;
|
||||||
|
private final SeenNotificationsProvider mSeenNotificationsProvider;
|
||||||
|
|
||||||
private NotificationStackScrollLayout mView;
|
private NotificationStackScrollLayout mView;
|
||||||
private boolean mFadeNotificationsOnDismiss;
|
private boolean mFadeNotificationsOnDismiss;
|
||||||
@@ -639,12 +643,14 @@ public class NotificationStackScrollLayoutController {
|
|||||||
GroupExpansionManager groupManager,
|
GroupExpansionManager groupManager,
|
||||||
@SilentHeader SectionHeaderController silentHeaderController,
|
@SilentHeader SectionHeaderController silentHeaderController,
|
||||||
NotifPipeline notifPipeline,
|
NotifPipeline notifPipeline,
|
||||||
|
NotifPipelineFlags notifPipelineFlags,
|
||||||
NotifCollection notifCollection,
|
NotifCollection notifCollection,
|
||||||
LockscreenShadeTransitionController lockscreenShadeTransitionController,
|
LockscreenShadeTransitionController lockscreenShadeTransitionController,
|
||||||
ShadeTransitionController shadeTransitionController,
|
ShadeTransitionController shadeTransitionController,
|
||||||
UiEventLogger uiEventLogger,
|
UiEventLogger uiEventLogger,
|
||||||
NotificationRemoteInputManager remoteInputManager,
|
NotificationRemoteInputManager remoteInputManager,
|
||||||
VisibilityLocationProviderDelegator visibilityLocationProviderDelegator,
|
VisibilityLocationProviderDelegator visibilityLocationProviderDelegator,
|
||||||
|
SeenNotificationsProvider seenNotificationsProvider,
|
||||||
ShadeController shadeController,
|
ShadeController shadeController,
|
||||||
InteractionJankMonitor jankMonitor,
|
InteractionJankMonitor jankMonitor,
|
||||||
StackStateLogger stackLogger,
|
StackStateLogger stackLogger,
|
||||||
@@ -683,10 +689,12 @@ public class NotificationStackScrollLayoutController {
|
|||||||
mGroupExpansionManager = groupManager;
|
mGroupExpansionManager = groupManager;
|
||||||
mSilentHeaderController = silentHeaderController;
|
mSilentHeaderController = silentHeaderController;
|
||||||
mNotifPipeline = notifPipeline;
|
mNotifPipeline = notifPipeline;
|
||||||
|
mNotifPipelineFlags = notifPipelineFlags;
|
||||||
mNotifCollection = notifCollection;
|
mNotifCollection = notifCollection;
|
||||||
mUiEventLogger = uiEventLogger;
|
mUiEventLogger = uiEventLogger;
|
||||||
mRemoteInputManager = remoteInputManager;
|
mRemoteInputManager = remoteInputManager;
|
||||||
mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator;
|
mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator;
|
||||||
|
mSeenNotificationsProvider = seenNotificationsProvider;
|
||||||
mShadeController = shadeController;
|
mShadeController = shadeController;
|
||||||
mFeatureFlags = featureFlags;
|
mFeatureFlags = featureFlags;
|
||||||
mNotificationTargetsHelper = notificationTargetsHelper;
|
mNotificationTargetsHelper = notificationTargetsHelper;
|
||||||
@@ -1212,7 +1220,11 @@ public class NotificationStackScrollLayoutController {
|
|||||||
// For more details, see: b/228790482
|
// For more details, see: b/228790482
|
||||||
&& !isInTransitionToKeyguard();
|
&& !isInTransitionToKeyguard();
|
||||||
|
|
||||||
mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
|
mView.updateEmptyShadeView(
|
||||||
|
shouldShow,
|
||||||
|
mZenModeController.areNotificationsHiddenInShade(),
|
||||||
|
mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()
|
||||||
|
&& mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
|
||||||
|
|
||||||
Trace.endSection();
|
Trace.endSection();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
|
|||||||
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
|
||||||
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
|
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
|
||||||
|
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider
|
||||||
|
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
|
||||||
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
|
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
|
||||||
import com.android.systemui.util.mockito.eq
|
import com.android.systemui.util.mockito.eq
|
||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
@@ -102,6 +104,31 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun unseenFilterUpdatesSeenProviderWhenSuppressing() {
|
||||||
|
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
|
||||||
|
|
||||||
|
// GIVEN: Keyguard is not showing, and a notification is present
|
||||||
|
keyguardRepository.setKeyguardShowing(false)
|
||||||
|
runKeyguardCoordinatorTest {
|
||||||
|
val fakeEntry = NotificationEntryBuilder().build()
|
||||||
|
collectionListener.onEntryAdded(fakeEntry)
|
||||||
|
|
||||||
|
// WHEN: The keyguard is now showing
|
||||||
|
keyguardRepository.setKeyguardShowing(true)
|
||||||
|
testScheduler.runCurrent()
|
||||||
|
|
||||||
|
// THEN: The notification is recognized as "seen" and is filtered out.
|
||||||
|
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
|
||||||
|
|
||||||
|
// WHEN: The filter is cleaned up
|
||||||
|
unseenFilter.onCleanup()
|
||||||
|
|
||||||
|
// THEN: The SeenNotificationProvider has been updated to reflect the suppression
|
||||||
|
assertThat(seenNotificationsProvider.hasFilteredOutSeenNotifications).isTrue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun unseenFilterAllowsNewNotif() {
|
fun unseenFilterAllowsNewNotif() {
|
||||||
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
|
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
|
||||||
@@ -204,6 +231,7 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
|
|||||||
testBlock: suspend KeyguardCoordinatorTestScope.() -> Unit
|
testBlock: suspend KeyguardCoordinatorTestScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
val testScope = TestScope(UnconfinedTestDispatcher())
|
val testScope = TestScope(UnconfinedTestDispatcher())
|
||||||
|
val seenNotificationsProvider = SeenNotificationsProviderImpl()
|
||||||
val keyguardCoordinator =
|
val keyguardCoordinator =
|
||||||
KeyguardCoordinator(
|
KeyguardCoordinator(
|
||||||
keyguardNotifVisibilityProvider,
|
keyguardNotifVisibilityProvider,
|
||||||
@@ -211,18 +239,20 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
|
|||||||
notifPipelineFlags,
|
notifPipelineFlags,
|
||||||
testScope.backgroundScope,
|
testScope.backgroundScope,
|
||||||
sectionHeaderVisibilityProvider,
|
sectionHeaderVisibilityProvider,
|
||||||
|
seenNotificationsProvider,
|
||||||
statusBarStateController,
|
statusBarStateController,
|
||||||
)
|
)
|
||||||
keyguardCoordinator.attach(notifPipeline)
|
keyguardCoordinator.attach(notifPipeline)
|
||||||
KeyguardCoordinatorTestScope(keyguardCoordinator, testScope).run {
|
testScope.runTest(dispatchTimeoutMs = 1.seconds.inWholeMilliseconds) {
|
||||||
testScheduler.advanceUntilIdle()
|
KeyguardCoordinatorTestScope(keyguardCoordinator, testScope, seenNotificationsProvider)
|
||||||
testScope.runTest(dispatchTimeoutMs = 1.seconds.inWholeMilliseconds) { testBlock() }
|
.testBlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class KeyguardCoordinatorTestScope(
|
private inner class KeyguardCoordinatorTestScope(
|
||||||
private val keyguardCoordinator: KeyguardCoordinator,
|
private val keyguardCoordinator: KeyguardCoordinator,
|
||||||
private val scope: TestScope,
|
private val scope: TestScope,
|
||||||
|
val seenNotificationsProvider: SeenNotificationsProvider,
|
||||||
) : CoroutineScope by scope {
|
) : CoroutineScope by scope {
|
||||||
val testScheduler: TestCoroutineScheduler
|
val testScheduler: TestCoroutineScheduler
|
||||||
get() = scope.testScheduler
|
get() = scope.testScheduler
|
||||||
|
|||||||
@@ -59,8 +59,10 @@ import com.android.systemui.statusbar.NotificationRemoteInputManager;
|
|||||||
import com.android.systemui.statusbar.RemoteInputController;
|
import com.android.systemui.statusbar.RemoteInputController;
|
||||||
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
import com.android.systemui.statusbar.SysuiStatusBarStateController;
|
||||||
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
|
||||||
|
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
import com.android.systemui.statusbar.notification.collection.NotifCollection;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
|
||||||
|
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl;
|
||||||
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
|
||||||
@@ -119,6 +121,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
|||||||
@Mock private GroupExpansionManager mGroupExpansionManager;
|
@Mock private GroupExpansionManager mGroupExpansionManager;
|
||||||
@Mock private SectionHeaderController mSilentHeaderController;
|
@Mock private SectionHeaderController mSilentHeaderController;
|
||||||
@Mock private NotifPipeline mNotifPipeline;
|
@Mock private NotifPipeline mNotifPipeline;
|
||||||
|
@Mock private NotifPipelineFlags mNotifPipelineFlags;
|
||||||
@Mock private NotifCollection mNotifCollection;
|
@Mock private NotifCollection mNotifCollection;
|
||||||
@Mock private UiEventLogger mUiEventLogger;
|
@Mock private UiEventLogger mUiEventLogger;
|
||||||
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
|
||||||
@@ -170,12 +173,14 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
|||||||
mGroupExpansionManager,
|
mGroupExpansionManager,
|
||||||
mSilentHeaderController,
|
mSilentHeaderController,
|
||||||
mNotifPipeline,
|
mNotifPipeline,
|
||||||
|
mNotifPipelineFlags,
|
||||||
mNotifCollection,
|
mNotifCollection,
|
||||||
mLockscreenShadeTransitionController,
|
mLockscreenShadeTransitionController,
|
||||||
mShadeTransitionController,
|
mShadeTransitionController,
|
||||||
mUiEventLogger,
|
mUiEventLogger,
|
||||||
mRemoteInputManager,
|
mRemoteInputManager,
|
||||||
mVisibilityLocationProviderDelegator,
|
mVisibilityLocationProviderDelegator,
|
||||||
|
new SeenNotificationsProviderImpl(),
|
||||||
mShadeController,
|
mShadeController,
|
||||||
mJankMonitor,
|
mJankMonitor,
|
||||||
mStackLogger,
|
mStackLogger,
|
||||||
@@ -228,14 +233,16 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
|||||||
mController.updateShowEmptyShadeView();
|
mController.updateShowEmptyShadeView();
|
||||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||||
/* visible= */ true,
|
/* visible= */ true,
|
||||||
/* notifVisibleInShade= */ true);
|
/* notifVisibleInShade= */ true,
|
||||||
|
/* areSeenNotifsFiltered= */false);
|
||||||
|
|
||||||
setupShowEmptyShadeViewState(false);
|
setupShowEmptyShadeViewState(false);
|
||||||
reset(mNotificationStackScrollLayout);
|
reset(mNotificationStackScrollLayout);
|
||||||
mController.updateShowEmptyShadeView();
|
mController.updateShowEmptyShadeView();
|
||||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||||
/* visible= */ false,
|
/* visible= */ false,
|
||||||
/* notifVisibleInShade= */ true);
|
/* notifVisibleInShade= */ true,
|
||||||
|
/* areSeenNotifsFiltered= */false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -248,14 +255,16 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
|||||||
mController.updateShowEmptyShadeView();
|
mController.updateShowEmptyShadeView();
|
||||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||||
/* visible= */ true,
|
/* visible= */ true,
|
||||||
/* notifVisibleInShade= */ false);
|
/* notifVisibleInShade= */ false,
|
||||||
|
/* areSeenNotifsFiltered= */false);
|
||||||
|
|
||||||
setupShowEmptyShadeViewState(false);
|
setupShowEmptyShadeViewState(false);
|
||||||
reset(mNotificationStackScrollLayout);
|
reset(mNotificationStackScrollLayout);
|
||||||
mController.updateShowEmptyShadeView();
|
mController.updateShowEmptyShadeView();
|
||||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||||
/* visible= */ false,
|
/* visible= */ false,
|
||||||
/* notifVisibleInShade= */ false);
|
/* notifVisibleInShade= */ false,
|
||||||
|
/* areSeenNotifsFiltered= */false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -274,14 +283,16 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
|
|||||||
mController.updateShowEmptyShadeView();
|
mController.updateShowEmptyShadeView();
|
||||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||||
/* visible= */ true,
|
/* visible= */ true,
|
||||||
/* notifVisibleInShade= */ false);
|
/* notifVisibleInShade= */ false,
|
||||||
|
/* areSeenNotifsFiltered= */false);
|
||||||
|
|
||||||
mController.setQsFullScreen(true);
|
mController.setQsFullScreen(true);
|
||||||
reset(mNotificationStackScrollLayout);
|
reset(mNotificationStackScrollLayout);
|
||||||
mController.updateShowEmptyShadeView();
|
mController.updateShowEmptyShadeView();
|
||||||
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
|
||||||
/* visible= */ true,
|
/* visible= */ true,
|
||||||
/* notifVisibleInShade= */ false);
|
/* notifVisibleInShade= */ false,
|
||||||
|
/* areSeenNotifsFiltered= */false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
|
|||||||
public void updateEmptyView_dndSuppressing() {
|
public void updateEmptyView_dndSuppressing() {
|
||||||
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
||||||
|
|
||||||
mStackScroller.updateEmptyShadeView(true, true);
|
mStackScroller.updateEmptyShadeView(true, true, false);
|
||||||
|
|
||||||
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
|
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
|
||||||
}
|
}
|
||||||
@@ -334,7 +334,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
|
|||||||
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
||||||
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
||||||
|
|
||||||
mStackScroller.updateEmptyShadeView(true, false);
|
mStackScroller.updateEmptyShadeView(true, false, false);
|
||||||
|
|
||||||
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
|
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
|
||||||
}
|
}
|
||||||
@@ -343,10 +343,10 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
|
|||||||
public void updateEmptyView_noNotificationsToDndSuppressing() {
|
public void updateEmptyView_noNotificationsToDndSuppressing() {
|
||||||
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
||||||
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
when(mEmptyShadeView.willBeGone()).thenReturn(true);
|
||||||
mStackScroller.updateEmptyShadeView(true, false);
|
mStackScroller.updateEmptyShadeView(true, false, false);
|
||||||
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
|
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
|
||||||
|
|
||||||
mStackScroller.updateEmptyShadeView(true, true);
|
mStackScroller.updateEmptyShadeView(true, true, false);
|
||||||
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
|
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user