Merge "Add unlock to see more messaging to notif footer" into tm-qpr-dev am: 437f91af5b am: cbed317cda
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20691784 Change-Id: Ia388f8d7d4c72b7a2ff9e94632a55c350404cdd2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user