Merge "Add unlock to see more messaging to notif footer" into tm-qpr-dev am: 437f91af5b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20691784

Change-Id: I6b65f48d3db1bb5092246345c1d633970ffa7d1e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Steve Elliott
2023-01-18 20:44:57 +00:00
committed by Automerger Merge Worker
7 changed files with 145 additions and 26 deletions

View File

@@ -26,6 +26,17 @@
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/unlock_prompt_footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
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"/>
<com.android.systemui.statusbar.notification.row.FooterViewButton
style="@style/TextAppearance.NotificationSectionHeaderButton"
android:id="@+id/manage_text"

View File

@@ -16,15 +16,22 @@
package com.android.systemui.statusbar.notification.row;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.StringRes;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.IndentingPrintWriter;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -41,6 +48,11 @@ public class FooterView extends StackScrollerDecorView {
private String mManageNotificationText;
private String mManageNotificationHistoryText;
// Footer label
private TextView mSeenNotifsFooterTextView;
private @StringRes int mSeenNotifsFilteredText;
private int mUnlockIconSize;
public FooterView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -73,10 +85,41 @@ public class FooterView extends StackScrollerDecorView {
super.onFinishInflate();
mClearAllButton = (FooterViewButton) findSecondaryView();
mManageButton = findViewById(R.id.manage_text);
mSeenNotifsFooterTextView = findViewById(R.id.unlock_prompt_footer);
updateResources();
updateText();
}
public void setFooterLabelTextAndIcon(@StringRes int text, @DrawableRes int icon) {
mSeenNotifsFilteredText = text;
if (mSeenNotifsFilteredText != 0) {
mSeenNotifsFooterTextView.setText(mSeenNotifsFilteredText);
} else {
mSeenNotifsFooterTextView.setText(null);
}
Drawable drawable;
if (icon == 0) {
drawable = null;
} else {
drawable = getResources().getDrawable(icon);
drawable.setBounds(0, 0, mUnlockIconSize, mUnlockIconSize);
}
mSeenNotifsFooterTextView.setCompoundDrawablesRelative(drawable, null, null, null);
updateFooterVisibilityMode();
}
private void updateFooterVisibilityMode() {
if (mSeenNotifsFilteredText != 0) {
mManageButton.setVisibility(View.GONE);
mClearAllButton.setVisibility(View.GONE);
mSeenNotifsFooterTextView.setVisibility(View.VISIBLE);
} else {
mManageButton.setVisibility(View.VISIBLE);
mClearAllButton.setVisibility(View.VISIBLE);
mSeenNotifsFooterTextView.setVisibility(View.GONE);
}
}
public void setManageButtonClickListener(OnClickListener listener) {
mManageButton.setOnClickListener(listener);
}
@@ -135,12 +178,19 @@ public class FooterView extends StackScrollerDecorView {
mClearAllButton.setTextColor(textColor);
mManageButton.setBackground(theme.getDrawable(R.drawable.notif_footer_btn_background));
mManageButton.setTextColor(textColor);
final @ColorInt int labelTextColor =
Utils.getColorAttrDefaultColor(mContext, android.R.attr.textColorPrimary);
mSeenNotifsFooterTextView.setTextColor(labelTextColor);
mSeenNotifsFooterTextView.setCompoundDrawableTintList(
ColorStateList.valueOf(labelTextColor));
}
private void updateResources() {
mManageNotificationText = getContext().getString(R.string.manage_notifications_text);
mManageNotificationHistoryText = getContext()
.getString(R.string.manage_notifications_history_text);
mUnlockIconSize = getResources()
.getDimensionPixelSize(R.dimen.notifications_unseen_footer_icon_size);
}
@Override

View File

@@ -538,6 +538,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private NotificationStackScrollLayoutController.TouchHandler mTouchHandler;
private final ScreenOffAnimationController mScreenOffAnimationController;
private boolean mShouldUseSplitNotificationShade;
private boolean mHasFilteredOutSeenNotifications;
private final ExpandableView.OnHeightChangedListener mOnChildHeightChangedListener =
new ExpandableView.OnHeightChangedListener() {
@@ -684,6 +685,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
updateFooter();
}
void setHasFilteredOutSeenNotifications(boolean hasFilteredOutSeenNotifications) {
mHasFilteredOutSeenNotifications = hasFilteredOutSeenNotifications;
}
@VisibleForTesting
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void updateFooter() {
@@ -4612,13 +4617,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
void updateEmptyShadeView(
boolean visible, boolean areNotificationsHiddenInShade, boolean areSeenNotifsFiltered) {
void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
if (areNotificationsHiddenInShade) {
updateEmptyShadeView(R.string.dnd_suppressing_shade_text, 0, 0);
} else if (areSeenNotifsFiltered) {
} else if (mHasFilteredOutSeenNotifications) {
updateEmptyShadeView(
R.string.no_unseen_notif_text,
R.string.unlock_to_see_notif_text,
@@ -4657,13 +4661,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) {
if (mFooterView == null) {
if (mFooterView == null || mNotificationStackSizeCalculator == null) {
return;
}
boolean animate = mIsExpanded && mAnimationsEnabled;
mFooterView.setVisible(visible, animate);
mFooterView.setSecondaryVisible(showDismissView, animate);
mFooterView.showHistory(showHistory);
if (mHasFilteredOutSeenNotifications) {
mFooterView.setFooterLabelTextAndIcon(
R.string.unlock_to_see_notif_text,
R.drawable.ic_friction_lock_closed);
} else {
mFooterView.setFooterLabelTextAndIcon(0, 0);
}
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)

View File

@@ -1242,11 +1242,7 @@ public class NotificationStackScrollLayoutController {
// For more details, see: b/228790482
&& !isInTransitionToKeyguard();
mView.updateEmptyShadeView(
shouldShow,
mZenModeController.areNotificationsHiddenInShade(),
mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()
&& mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
Trace.endSection();
}
@@ -1942,6 +1938,9 @@ public class NotificationStackScrollLayoutController {
@Override
public void setNotifStats(@NonNull NotifStats notifStats) {
mNotifStats = notifStats;
mView.setHasFilteredOutSeenNotifications(
mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()
&& mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
updateFooter();
updateShowEmptyShadeView();
}

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row;
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
@@ -98,5 +100,16 @@ public class FooterViewTest extends SysuiTestCase {
mView.setSecondaryVisible(true /* visible */, true /* animate */);
}
@Test
public void testSetFooterLabelTextAndIcon() {
mView.setFooterLabelTextAndIcon(
R.string.unlock_to_see_notif_text,
R.drawable.ic_friction_lock_closed);
assertThat(mView.findViewById(R.id.manage_text).getVisibility()).isEqualTo(View.GONE);
assertThat(mView.findSecondaryView().getVisibility()).isEqualTo(View.GONE);
assertThat(mView.findViewById(R.id.unlock_prompt_footer).getVisibility())
.isEqualTo(View.VISIBLE);
}
}

View File

@@ -21,6 +21,7 @@ import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -65,6 +66,7 @@ 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.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.NotifStats;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -139,6 +141,9 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
@Captor
private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
private final SeenNotificationsProviderImpl mSeenNotificationsProvider =
new SeenNotificationsProviderImpl();
private NotificationStackScrollLayoutController mController;
@Before
@@ -180,7 +185,7 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mUiEventLogger,
mRemoteInputManager,
mVisibilityLocationProviderDelegator,
new SeenNotificationsProviderImpl(),
mSeenNotificationsProvider,
mShadeController,
mJankMonitor,
mStackLogger,
@@ -233,16 +238,14 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ true,
/* notifVisibleInShade= */ true,
/* areSeenNotifsFiltered= */false);
/* notifVisibleInShade= */ true);
setupShowEmptyShadeViewState(false);
reset(mNotificationStackScrollLayout);
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ false,
/* notifVisibleInShade= */ true,
/* areSeenNotifsFiltered= */false);
/* notifVisibleInShade= */ true);
}
@Test
@@ -255,16 +258,14 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ true,
/* notifVisibleInShade= */ false,
/* areSeenNotifsFiltered= */false);
/* notifVisibleInShade= */ false);
setupShowEmptyShadeViewState(false);
reset(mNotificationStackScrollLayout);
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ false,
/* notifVisibleInShade= */ false,
/* areSeenNotifsFiltered= */false);
/* notifVisibleInShade= */ false);
}
@Test
@@ -283,16 +284,14 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ true,
/* notifVisibleInShade= */ false,
/* areSeenNotifsFiltered= */false);
/* notifVisibleInShade= */ false);
mController.setQsFullScreen(true);
reset(mNotificationStackScrollLayout);
mController.updateShowEmptyShadeView();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(
/* visible= */ true,
/* notifVisibleInShade= */ false,
/* areSeenNotifsFiltered= */false);
/* notifVisibleInShade= */ false);
}
@Test
@@ -400,6 +399,17 @@ public class NotificationStackScrollLayoutControllerTest extends SysuiTestCase {
verify(mNotificationStackScrollLayout).setIsRemoteInputActive(true);
}
@Test
public void testSetNotifStats_updatesHasFilteredOutSeenNotifications() {
when(mNotifPipelineFlags.getShouldFilterUnseenNotifsOnKeyguard()).thenReturn(true);
mSeenNotificationsProvider.setHasFilteredOutSeenNotifications(true);
mController.attach(mNotificationStackScrollLayout);
mController.getNotifStackController().setNotifStats(NotifStats.getEmpty());
verify(mNotificationStackScrollLayout).setHasFilteredOutSeenNotifications(true);
verify(mNotificationStackScrollLayout).updateFooter();
verify(mNotificationStackScrollLayout).updateEmptyShadeView(anyBoolean(), anyBoolean());
}
private LogMaker logMatcher(int category, int type) {
return argThat(new LogMatcher(category, type));
}

View File

@@ -30,6 +30,7 @@ import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
@@ -53,6 +54,7 @@ import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
@@ -328,7 +330,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
public void updateEmptyView_dndSuppressing() {
when(mEmptyShadeView.willBeGone()).thenReturn(true);
mStackScroller.updateEmptyShadeView(true, true, false);
mStackScroller.updateEmptyShadeView(true, true);
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
}
@@ -338,7 +340,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mStackScroller.setEmptyShadeView(mEmptyShadeView);
when(mEmptyShadeView.willBeGone()).thenReturn(true);
mStackScroller.updateEmptyShadeView(true, false, false);
mStackScroller.updateEmptyShadeView(true, false);
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
}
@@ -347,10 +349,10 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
public void updateEmptyView_noNotificationsToDndSuppressing() {
mStackScroller.setEmptyShadeView(mEmptyShadeView);
when(mEmptyShadeView.willBeGone()).thenReturn(true);
mStackScroller.updateEmptyShadeView(true, false, false);
mStackScroller.updateEmptyShadeView(true, false);
verify(mEmptyShadeView).setText(R.string.empty_shade_text);
mStackScroller.updateEmptyShadeView(true, true, false);
mStackScroller.updateEmptyShadeView(true, true);
verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
}
@@ -818,6 +820,29 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
assertEquals(0f, mAmbientState.getStackY());
}
@Test
public void hasFilteredOutSeenNotifs_updateFooter() {
mStackScroller.setCurrentUserSetup(true);
// add footer
mStackScroller.inflateFooterView();
TextView footerLabel =
mStackScroller.mFooterView.requireViewById(R.id.unlock_prompt_footer);
mStackScroller.setHasFilteredOutSeenNotifications(true);
mStackScroller.updateFooter();
assertThat(footerLabel.getVisibility()).isEqualTo(View.VISIBLE);
}
@Test
public void hasFilteredOutSeenNotifs_updateEmptyShadeView() {
mStackScroller.setHasFilteredOutSeenNotifications(true);
mStackScroller.updateEmptyShadeView(true, false);
verify(mEmptyShadeView).setFooterText(not(0));
}
private void setBarStateForTest(int state) {
// Can't inject this through the listener or we end up on the actual implementation
// rather than the mock because the spy just coppied the anonymous inner /shruggie.