Merge "Add "Sensitive Content" public view" into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index cdc8bc1..a49a66f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -16,12 +16,18 @@
package com.android.systemui.statusbar.notification.row;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_PUBLIC;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_SENSITIVE_CONTENT;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_NONE;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
+import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -36,7 +42,9 @@
import static org.mockito.Mockito.when;
import android.app.Notification;
+import android.app.Person;
import android.content.Context;
+import android.graphics.drawable.Icon;
import android.os.AsyncTask;
import android.os.CancellationSignal;
import android.os.Handler;
@@ -66,6 +74,7 @@
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
+import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
@@ -155,8 +164,8 @@
@Test
public void testIncreasedHeadsUpBeingUsed() {
- BindParams params = new BindParams();
- params.usesIncreasedHeadsUpHeight = true;
+ BindParams params = new BindParams(false, false, /* usesIncreasedHeadsUpHeight */ true,
+ REDACTION_TYPE_NONE);
Notification.Builder builder = spy(mBuilder);
mNotificationInflater.inflateNotificationViews(
mRow.getEntry(),
@@ -166,14 +175,15 @@
FLAG_CONTENT_VIEW_ALL,
builder,
mContext,
+ mContext,
mSmartReplyStateInflater);
verify(builder).createHeadsUpContentView(true);
}
@Test
public void testIncreasedHeightBeingUsed() {
- BindParams params = new BindParams();
- params.usesIncreasedHeight = true;
+ BindParams params = new BindParams(false, /* usesIncreasedHeight */ true, false,
+ REDACTION_TYPE_NONE);
Notification.Builder builder = spy(mBuilder);
mNotificationInflater.inflateNotificationViews(
mRow.getEntry(),
@@ -183,6 +193,7 @@
FLAG_CONTENT_VIEW_ALL,
builder,
mContext,
+ mContext,
mSmartReplyStateInflater);
verify(builder).createContentView(true);
}
@@ -207,7 +218,7 @@
mRow.getEntry().getSbn().getNotification().contentView
= new RemoteViews(mContext.getPackageName(), com.android.systemui.res.R.layout.status_bar);
inflateAndWait(true /* expectingException */, mNotificationInflater, FLAG_CONTENT_VIEW_ALL,
- mRow);
+ REDACTION_TYPE_NONE, mRow);
assertTrue(mRow.getPrivateLayout().getChildCount() == 0);
verify(mRow, times(0)).onNotificationUpdated();
}
@@ -227,7 +238,7 @@
mRow.getEntry(),
mRow,
FLAG_CONTENT_VIEW_ALL,
- new BindParams(),
+ new BindParams(false, false, false, REDACTION_TYPE_NONE),
false /* forceInflate */,
null /* callback */);
Assert.assertNull(mRow.getEntry().getRunningTask());
@@ -287,7 +298,7 @@
mBuilder.setCustomContentView(new RemoteViews(getContext().getPackageName(),
R.layout.custom_view_dark));
RemoteViews decoratedMediaView = mBuilder.createContentView();
- Assert.assertFalse("The decorated media style doesn't allow a view to be reapplied!",
+ assertFalse("The decorated media style doesn't allow a view to be reapplied!",
NotificationContentInflater.canReapplyRemoteView(mediaView, decoratedMediaView));
}
@@ -385,7 +396,8 @@
mRow.getPrivateLayout().removeAllViews();
mRow.getEntry().getSbn().getNotification().contentView =
new RemoteViews(mContext.getPackageName(), R.layout.invalid_notification_height);
- inflateAndWait(true, mNotificationInflater, FLAG_CONTENT_VIEW_ALL, mRow);
+ inflateAndWait(true, mNotificationInflater, FLAG_CONTENT_VIEW_ALL, REDACTION_TYPE_NONE,
+ mRow);
assertEquals(0, mRow.getPrivateLayout().getChildCount());
verify(mRow, times(0)).onNotificationUpdated();
}
@@ -455,16 +467,88 @@
assertNull(mRow.getEntry().getPromotedNotificationContentModel());
}
+ @Test
+ @EnableFlags(LockscreenOtpRedaction.FLAG_NAME)
+ public void testSensitiveContentPublicView_messageStyle() throws Exception {
+ String displayName = "Display Name";
+ String messageText = "Message Text";
+ String contentText = "Content Text";
+ Icon personIcon = Icon.createWithResource(mContext,
+ com.android.systemui.res.R.drawable.ic_person);
+ Person testPerson = new Person.Builder()
+ .setName(displayName)
+ .setIcon(personIcon)
+ .build();
+ Notification.MessagingStyle messagingStyle = new Notification.MessagingStyle(testPerson);
+ messagingStyle.addMessage(new Notification.MessagingStyle.Message(messageText,
+ System.currentTimeMillis(), testPerson));
+ messagingStyle.setConversationType(Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL);
+ messagingStyle.setShortcutIcon(personIcon);
+ Notification messageNotif = new Notification.Builder(mContext).setSmallIcon(
+ com.android.systemui.res.R.drawable.ic_person).setStyle(messagingStyle).build();
+ ExpandableNotificationRow row = mHelper.createRow(messageNotif);
+ inflateAndWait(false, mNotificationInflater, FLAG_CONTENT_VIEW_PUBLIC,
+ REDACTION_TYPE_SENSITIVE_CONTENT, row);
+ NotificationContentView publicView = row.getPublicLayout();
+ assertNotNull(publicView);
+ // The display name should be included, but not the content or message text
+ assertFalse(hasText(publicView, messageText));
+ assertFalse(hasText(publicView, contentText));
+ assertTrue(hasText(publicView, displayName));
+ }
+
+ @Test
+ @EnableFlags(LockscreenOtpRedaction.FLAG_NAME)
+ public void testSensitiveContentPublicView_nonMessageStyle() throws Exception {
+ String contentTitle = "Content Title";
+ String contentText = "Content Text";
+ Notification notif = new Notification.Builder(mContext).setSmallIcon(
+ com.android.systemui.res.R.drawable.ic_person)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .build();
+ ExpandableNotificationRow row = mHelper.createRow(notif);
+ inflateAndWait(false, mNotificationInflater, FLAG_CONTENT_VIEW_PUBLIC,
+ REDACTION_TYPE_SENSITIVE_CONTENT, row);
+ NotificationContentView publicView = row.getPublicLayout();
+ assertNotNull(publicView);
+ assertFalse(hasText(publicView, contentText));
+ assertTrue(hasText(publicView, contentTitle));
+
+ // The standard public view should not use the content title or text
+ inflateAndWait(false, mNotificationInflater, FLAG_CONTENT_VIEW_PUBLIC,
+ REDACTION_TYPE_PUBLIC, row);
+ publicView = row.getPublicLayout();
+ assertFalse(hasText(publicView, contentText));
+ assertFalse(hasText(publicView, contentTitle));
+ }
+
+ private static boolean hasText(ViewGroup parent, CharSequence text) {
+ for (int i = 0; i < parent.getChildCount(); i++) {
+ View child = parent.getChildAt(i);
+ if (child instanceof ViewGroup) {
+ if (hasText((ViewGroup) child, text)) {
+ return true;
+ }
+ } else if (child instanceof TextView) {
+ return ((TextView) child).getText().toString().contains(text);
+ }
+ }
+ return false;
+ }
+
private static void inflateAndWait(NotificationContentInflater inflater,
@InflationFlag int contentToInflate,
ExpandableNotificationRow row)
throws Exception {
- inflateAndWait(false /* expectingException */, inflater, contentToInflate, row);
+ inflateAndWait(false /* expectingException */, inflater, contentToInflate,
+ REDACTION_TYPE_NONE, row);
}
private static void inflateAndWait(boolean expectingException,
NotificationContentInflater inflater,
@InflationFlag int contentToInflate,
+ @RedactionType int redactionType,
ExpandableNotificationRow row) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(1);
final ExceptionHolder exceptionHolder = new ExceptionHolder();
@@ -492,7 +576,7 @@
row.getEntry(),
row,
contentToInflate,
- new BindParams(),
+ new BindParams(false, false, false, redactionType),
false /* forceInflate */,
callback /* callback */);
assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS));
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index 9fb72fb..2aeebe3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -18,6 +18,7 @@
import android.app.Notification
import android.app.Person
import android.content.Context
+import android.graphics.drawable.Icon
import android.os.AsyncTask
import android.os.Build
import android.os.CancellationSignal
@@ -34,6 +35,10 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_NONE
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_PUBLIC
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_SENSITIVE_CONTENT
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -45,6 +50,7 @@
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
@@ -138,14 +144,14 @@
@Test
fun testIncreasedHeadsUpBeingUsed() {
- val params = BindParams()
- params.usesIncreasedHeadsUpHeight = true
+ val params =
+ BindParams(false, false, /* usesIncreasedHeadsUpHeight */ true, REDACTION_TYPE_NONE)
val builder = spy(builder)
notificationInflater.inflateNotificationViews(
row.entry,
row,
params,
- true /* inflateSynchronously */,
+ true, /* inflateSynchronously */
FLAG_CONTENT_VIEW_ALL,
builder,
mContext,
@@ -157,14 +163,13 @@
@Test
fun testIncreasedHeightBeingUsed() {
- val params = BindParams()
- params.usesIncreasedHeight = true
+ val params = BindParams(false, /* usesIncreasedHeight */ true, false, REDACTION_TYPE_NONE)
val builder = spy(builder)
notificationInflater.inflateNotificationViews(
row.entry,
row,
params,
- true /* inflateSynchronously */,
+ true, /* inflateSynchronously */
FLAG_CONTENT_VIEW_ALL,
builder,
mContext,
@@ -193,15 +198,18 @@
row.entry.sbn.notification.contentView =
RemoteViews(mContext.packageName, R.layout.status_bar)
inflateAndWait(
- true /* expectingException */,
+ true, /* expectingException */
notificationInflater,
FLAG_CONTENT_VIEW_ALL,
+ REDACTION_TYPE_NONE,
row,
)
Assert.assertTrue(row.privateLayout.childCount == 0)
verify(row, times(0)).onNotificationUpdated()
}
+ @Test fun testInflationOfSensitiveContentPublicView() {}
+
@Test
fun testAsyncTaskRemoved() {
row.entry.abortTask()
@@ -217,8 +225,8 @@
row.entry,
row,
FLAG_CONTENT_VIEW_ALL,
- BindParams(),
- false /* forceInflate */,
+ BindParams(false, false, false, REDACTION_TYPE_NONE),
+ false, /* forceInflate */
null, /* callback */
)
Assert.assertNull(row.entry.runningTask)
@@ -431,7 +439,7 @@
mContext.packageName,
com.android.systemui.tests.R.layout.invalid_notification_height,
)
- inflateAndWait(true, notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+ inflateAndWait(true, notificationInflater, FLAG_CONTENT_VIEW_ALL, REDACTION_TYPE_NONE, row)
Assert.assertEquals(0, row.privateLayout.childCount.toLong())
verify(row, times(0)).onNotificationUpdated()
}
@@ -440,7 +448,13 @@
@Test
fun testInflatePublicSingleLineView() {
row.publicLayout.removeAllViews()
- inflateAndWait(false, notificationInflater, FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE, row)
+ inflateAndWait(
+ false,
+ notificationInflater,
+ FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+ REDACTION_TYPE_NONE,
+ row,
+ )
Assert.assertNotNull(row.publicLayout.mSingleLineView)
Assert.assertTrue(row.publicLayout.mSingleLineView is HybridNotificationView)
}
@@ -461,6 +475,7 @@
false,
notificationInflater,
FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+ REDACTION_TYPE_NONE,
messagingRow,
)
Assert.assertNotNull(messagingRow.publicLayout.mSingleLineView)
@@ -530,6 +545,80 @@
Assert.assertNull(row.entry.promotedNotificationContentModel)
}
+ @Test
+ @Throws(java.lang.Exception::class)
+ @EnableFlags(LockscreenOtpRedaction.FLAG_NAME)
+ fun testSensitiveContentPublicView_messageStyle() {
+ val displayName = "Display Name"
+ val messageText = "Message Text"
+ val contentText = "Content Text"
+ val personIcon = Icon.createWithResource(mContext, R.drawable.ic_person)
+ val testPerson = Person.Builder().setName(displayName).setIcon(personIcon).build()
+ val messagingStyle = Notification.MessagingStyle(testPerson)
+ messagingStyle.addMessage(
+ Notification.MessagingStyle.Message(messageText, System.currentTimeMillis(), testPerson)
+ )
+ messagingStyle.setConversationType(Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL)
+ messagingStyle.setShortcutIcon(personIcon)
+ val messageNotif =
+ Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_person)
+ .setStyle(messagingStyle)
+ .build()
+ val newRow: ExpandableNotificationRow = testHelper.createRow(messageNotif)
+ inflateAndWait(
+ false,
+ notificationInflater,
+ FLAG_CONTENT_VIEW_PUBLIC,
+ REDACTION_TYPE_SENSITIVE_CONTENT,
+ newRow,
+ )
+ // The display name should be included, but not the content or message text
+ val publicView = newRow.publicLayout
+ Assert.assertNotNull(publicView)
+ Assert.assertFalse(hasText(publicView, messageText))
+ Assert.assertFalse(hasText(publicView, contentText))
+ Assert.assertTrue(hasText(publicView, displayName))
+ }
+
+ @Test
+ @Throws(java.lang.Exception::class)
+ @EnableFlags(LockscreenOtpRedaction.FLAG_NAME)
+ fun testSensitiveContentPublicView_nonMessageStyle() {
+ val contentTitle = "Content Title"
+ val contentText = "Content Text"
+ val notif =
+ Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .build()
+ val newRow: ExpandableNotificationRow = testHelper.createRow(notif)
+ inflateAndWait(
+ false,
+ notificationInflater,
+ FLAG_CONTENT_VIEW_PUBLIC,
+ REDACTION_TYPE_SENSITIVE_CONTENT,
+ newRow,
+ )
+ var publicView = newRow.publicLayout
+ Assert.assertNotNull(publicView)
+ Assert.assertFalse(hasText(publicView, contentText))
+ Assert.assertTrue(hasText(publicView, contentTitle))
+
+ // The standard public view should not use the content title or text
+ inflateAndWait(
+ false,
+ notificationInflater,
+ FLAG_CONTENT_VIEW_PUBLIC,
+ REDACTION_TYPE_PUBLIC,
+ newRow,
+ )
+ publicView = newRow.publicLayout
+ Assert.assertFalse(hasText(publicView, contentText))
+ Assert.assertFalse(hasText(publicView, contentTitle))
+ }
+
private class ExceptionHolder {
var exception: Exception? = null
}
@@ -568,13 +657,20 @@
@InflationFlag contentToInflate: Int,
row: ExpandableNotificationRow,
) {
- inflateAndWait(false /* expectingException */, inflater, contentToInflate, row)
+ inflateAndWait(
+ false /* expectingException */,
+ inflater,
+ contentToInflate,
+ REDACTION_TYPE_NONE,
+ row,
+ )
}
private fun inflateAndWait(
expectingException: Boolean,
inflater: NotificationRowContentBinderImpl,
@InflationFlag contentToInflate: Int,
+ @RedactionType redactionType: Int,
row: ExpandableNotificationRow,
) {
val countDownLatch = CountDownLatch(1)
@@ -603,12 +699,26 @@
row.entry,
row,
contentToInflate,
- BindParams(),
- false /* forceInflate */,
+ BindParams(false, false, false, redactionType),
+ false, /* forceInflate */
callback, /* callback */
)
Assert.assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS))
exceptionHolder.exception?.let { throw it }
}
+
+ fun hasText(parent: ViewGroup, text: CharSequence): Boolean {
+ for (i in 0 until parent.childCount) {
+ val child = parent.getChildAt(i)
+ if (child is ViewGroup) {
+ if (hasText(child, text)) {
+ return true
+ }
+ } else if (child is TextView) {
+ return child.text.toString().contains(text)
+ }
+ }
+ return false
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
index 80e8f55..d83acf3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.inflation;
import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_NONE;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_SENSITIVE_CONTENT;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
@@ -186,6 +187,9 @@
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC);
if (AsyncHybridViewInflation.isEnabled()) {
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_SINGLE_LINE);
+ if (LockscreenOtpRedaction.isSingleLineViewEnabled()) {
+ params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
+ }
}
mRowContentBindStage.requestRebind(entry, null);
}
@@ -256,10 +260,10 @@
params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED);
params.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
params.setUseMinimized(isMinimized);
- // TODO b/358403414: use the different types of redaction
- boolean needsRedaction = inflaterParams.getRedactionType() != REDACTION_TYPE_NONE;
+ int redactionType = inflaterParams.getRedactionType();
- if (needsRedaction) {
+ params.setRedactionType(redactionType);
+ if (redactionType != REDACTION_TYPE_NONE) {
params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC);
} else {
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC);
@@ -276,8 +280,8 @@
}
if (LockscreenOtpRedaction.isSingleLineViewEnabled()) {
-
- if (inflaterParams.isChildInGroup() && needsRedaction) {
+ if (inflaterParams.isChildInGroup()
+ && redactionType == REDACTION_TYPE_SENSITIVE_CONTENT) {
params.requireContentViews(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
} else {
params.markContentViewsFreeable(FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 6eeb80d..878a4aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_SENSITIVE_CONTENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
@@ -25,6 +26,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
+import android.app.Notification.MessagingStyle;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
@@ -161,9 +163,7 @@
entry,
mConversationProcessor,
row,
- bindParams.isMinimized,
- bindParams.usesIncreasedHeight,
- bindParams.usesIncreasedHeadsUpHeight,
+ bindParams,
callback,
mRemoteInputManager.getRemoteViewsOnClickHandler(),
/* isMediaFlagEnabled = */ mIsMediaInQS,
@@ -187,13 +187,13 @@
boolean inflateSynchronously,
@InflationFlag int reInflateFlags,
Notification.Builder builder,
+ Context systemUiContext,
Context packageContext,
SmartReplyStateInflater smartRepliesInflater) {
InflationProgress result = createRemoteViews(reInflateFlags,
builder,
- bindParams.isMinimized,
- bindParams.usesIncreasedHeight,
- bindParams.usesIncreasedHeadsUpHeight,
+ bindParams,
+ systemUiContext,
packageContext,
row,
mNotifLayoutInflaterFactoryProvider,
@@ -411,8 +411,8 @@
}
private static InflationProgress createRemoteViews(@InflationFlag int reInflateFlags,
- Notification.Builder builder, boolean isMinimized, boolean usesIncreasedHeight,
- boolean usesIncreasedHeadsUpHeight, Context packageContext,
+ Notification.Builder builder, BindParams bindParams, Context systemUiContext,
+ Context packageContext,
ExpandableNotificationRow row,
NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider,
HeadsUpStyleProvider headsUpStyleProvider,
@@ -423,13 +423,13 @@
if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
logger.logAsyncTaskProgress(entryForLogging, "creating contracted remote view");
- result.newContentView = createContentView(builder, isMinimized,
- usesIncreasedHeight);
+ result.newContentView = createContentView(builder, bindParams.isMinimized,
+ bindParams.usesIncreasedHeight);
}
if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) {
logger.logAsyncTaskProgress(entryForLogging, "creating expanded remote view");
- result.newExpandedView = createExpandedView(builder, isMinimized);
+ result.newExpandedView = createExpandedView(builder, bindParams.isMinimized);
}
if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
@@ -439,13 +439,20 @@
result.newHeadsUpView = builder.createCompactHeadsUpContentView();
} else {
result.newHeadsUpView = builder.createHeadsUpContentView(
- usesIncreasedHeadsUpHeight);
+ bindParams.usesIncreasedHeadsUpHeight);
}
}
if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
logger.logAsyncTaskProgress(entryForLogging, "creating public remote view");
- result.newPublicView = builder.makePublicContentView(isMinimized);
+ if (LockscreenOtpRedaction.isEnabled()
+ && bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT) {
+ result.newPublicView = createSensitiveContentMessageNotification(
+ row.getEntry().getSbn().getNotification(), builder.getStyle(),
+ systemUiContext, packageContext).createContentView(true);
+ } else {
+ result.newPublicView = builder.makePublicContentView(bindParams.isMinimized);
+ }
}
if (AsyncGroupHeaderViewInflation.isEnabled()) {
@@ -473,6 +480,42 @@
});
}
+ private static Notification.Builder createSensitiveContentMessageNotification(
+ Notification original,
+ Notification.Style originalStyle,
+ Context systemUiContext,
+ Context packageContext) {
+ Notification.Builder redacted =
+ new Notification.Builder(packageContext, original.getChannelId());
+ redacted.setContentTitle(original.extras.getCharSequence(Notification.EXTRA_TITLE));
+ CharSequence redactedMessage = systemUiContext.getString(
+ R.string.redacted_notification_single_line_text
+ );
+
+ if (originalStyle instanceof MessagingStyle oldStyle) {
+ MessagingStyle newStyle = new MessagingStyle(oldStyle.getUser());
+ newStyle.setConversationTitle(oldStyle.getConversationTitle());
+ newStyle.setGroupConversation(false);
+ newStyle.setConversationType(oldStyle.getConversationType());
+ newStyle.setShortcutIcon(oldStyle.getShortcutIcon());
+ newStyle.setBuilder(redacted);
+ MessagingStyle.Message latestMessage =
+ MessagingStyle.findLatestIncomingMessage(oldStyle.getMessages());
+ if (latestMessage != null) {
+ MessagingStyle.Message newMessage = new MessagingStyle.Message(redactedMessage,
+ latestMessage.getTimestamp(), latestMessage.getSenderPerson());
+ newStyle.addMessage(newMessage);
+ }
+ redacted.setStyle(newStyle);
+ } else {
+ redacted.setContentText(redactedMessage);
+ }
+ redacted.setLargeIcon(original.getLargeIcon());
+ redacted.setSmallIcon(original.getSmallIcon());
+ return redacted;
+ }
+
+
private static void setNotifsViewsInflaterFactory(InflationProgress result,
ExpandableNotificationRow row,
NotifLayoutInflaterFactory.Provider notifLayoutInflaterFactoryProvider) {
@@ -1118,10 +1161,8 @@
private final NotificationEntry mEntry;
private final Context mContext;
private final boolean mInflateSynchronously;
- private final boolean mIsMinimized;
- private final boolean mUsesIncreasedHeight;
+ private final BindParams mBindParams;
private final InflationCallback mCallback;
- private final boolean mUsesIncreasedHeadsUpHeight;
private final @InflationFlag int mReInflateFlags;
private final NotifRemoteViewCache mRemoteViewCache;
private final Executor mInflationExecutor;
@@ -1145,9 +1186,7 @@
NotificationEntry entry,
ConversationNotificationProcessor conversationProcessor,
ExpandableNotificationRow row,
- boolean isMinimized,
- boolean usesIncreasedHeight,
- boolean usesIncreasedHeadsUpHeight,
+ BindParams bindParams,
InflationCallback callback,
RemoteViews.InteractionHandler remoteViewClickHandler,
boolean isMediaFlagEnabled,
@@ -1164,9 +1203,7 @@
mRemoteViewCache = cache;
mSmartRepliesInflater = smartRepliesInflater;
mContext = mRow.getContext();
- mIsMinimized = isMinimized;
- mUsesIncreasedHeight = usesIncreasedHeight;
- mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight;
+ mBindParams = bindParams;
mRemoteViewClickHandler = remoteViewClickHandler;
mCallback = callback;
mConversationProcessor = conversationProcessor;
@@ -1236,8 +1273,7 @@
mEntry, recoveredBuilder, mLogger);
}
InflationProgress inflationProgress = createRemoteViews(mReInflateFlags,
- recoveredBuilder, mIsMinimized, mUsesIncreasedHeight,
- mUsesIncreasedHeadsUpHeight, packageContext, mRow,
+ recoveredBuilder, mBindParams, mContext, packageContext, mRow,
mNotifLayoutInflaterFactoryProvider, mHeadsUpStyleProvider, mLogger);
mLogger.logAsyncTaskProgress(mEntry,
@@ -1320,7 +1356,7 @@
mCancellationSignal = apply(
mInflationExecutor,
mInflateSynchronously,
- mIsMinimized,
+ mBindParams.isMinimized,
result,
mReInflateFlags,
mRemoteViewCache,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
index 07384af..1cef879 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinder.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -141,20 +143,33 @@
*/
class BindParams {
+ public BindParams(boolean minimized, boolean increasedHeight,
+ boolean increasedHeadsUpHeight, int redaction) {
+ isMinimized = minimized;
+ usesIncreasedHeight = increasedHeight;
+ usesIncreasedHeadsUpHeight = increasedHeadsUpHeight;
+ redactionType = redaction;
+ }
+
/**
* Bind a minimized version of the content views.
*/
- public boolean isMinimized;
+ public final boolean isMinimized;
/**
* Use increased height when binding contracted view.
*/
- public boolean usesIncreasedHeight;
+ public final boolean usesIncreasedHeight;
/**
* Use increased height when binding heads up views.
*/
- public boolean usesIncreasedHeadsUpHeight;
+ public final boolean usesIncreasedHeadsUpHeight;
+
+ /**
+ * Controls the type of public view to show, if a public view is requested
+ */
+ public final @RedactionType int redactionType;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 7dcb2de..e4e1398 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -17,6 +17,7 @@
import android.annotation.SuppressLint
import android.app.Notification
+import android.app.Notification.MessagingStyle
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.ApplicationInfo
@@ -42,6 +43,7 @@
import com.android.systemui.dagger.qualifiers.NotifInflation
import com.android.systemui.res.R
import com.android.systemui.statusbar.InflationTask
+import com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_SENSITIVE_CONTENT
import com.android.systemui.statusbar.NotificationRemoteInputManager
import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
import com.android.systemui.statusbar.notification.InflationException
@@ -142,9 +144,7 @@
entry,
conversationProcessor,
row,
- bindParams.isMinimized,
- bindParams.usesIncreasedHeight,
- bindParams.usesIncreasedHeadsUpHeight,
+ bindParams,
callback,
remoteInputManager.remoteViewsOnClickHandler,
/* isMediaFlagEnabled = */ smartReplyStateInflater,
@@ -178,10 +178,8 @@
reInflateFlags = reInflateFlags,
entry = entry,
builder = builder,
- isMinimized = bindParams.isMinimized,
- usesIncreasedHeight = bindParams.usesIncreasedHeight,
- usesIncreasedHeadsUpHeight = bindParams.usesIncreasedHeadsUpHeight,
- systemUIContext = systemUIContext,
+ bindParams,
+ systemUiContext = systemUIContext,
packageContext = packageContext,
row = row,
notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
@@ -370,9 +368,7 @@
private val entry: NotificationEntry,
private val conversationProcessor: ConversationNotificationProcessor,
private val row: ExpandableNotificationRow,
- private val isMinimized: Boolean,
- private val usesIncreasedHeight: Boolean,
- private val usesIncreasedHeadsUpHeight: Boolean,
+ private val bindParams: BindParams,
private val callback: InflationCallback?,
private val remoteViewClickHandler: InteractionHandler?,
private val smartRepliesInflater: SmartReplyStateInflater,
@@ -440,10 +436,8 @@
reInflateFlags = reInflateFlags,
entry = entry,
builder = recoveredBuilder,
- isMinimized = isMinimized,
- usesIncreasedHeight = usesIncreasedHeight,
- usesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight,
- systemUIContext = context,
+ bindParams = bindParams,
+ systemUiContext = context,
packageContext = packageContext,
row = row,
notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
@@ -513,7 +507,7 @@
apply(
inflationExecutor,
inflateSynchronously,
- isMinimized,
+ bindParams.isMinimized,
progress,
reInflateFlags,
remoteViewCache,
@@ -670,10 +664,8 @@
@InflationFlag reInflateFlags: Int,
entry: NotificationEntry,
builder: Notification.Builder,
- isMinimized: Boolean,
- usesIncreasedHeight: Boolean,
- usesIncreasedHeadsUpHeight: Boolean,
- systemUIContext: Context,
+ bindParams: BindParams,
+ systemUiContext: Context,
packageContext: Context,
row: ExpandableNotificationRow,
notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
@@ -705,9 +697,10 @@
createRemoteViews(
reInflateFlags = reInflateFlags,
builder = builder,
- isMinimized = isMinimized,
- usesIncreasedHeight = usesIncreasedHeight,
- usesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight,
+ bindParams = bindParams,
+ entry = entry,
+ systemUiContext = systemUiContext,
+ packageContext = packageContext,
row = row,
notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
headsUpStyleProvider = headsUpStyleProvider,
@@ -724,7 +717,7 @@
notification = entry.sbn.notification,
messagingStyle = messagingStyle,
builder = builder,
- systemUiContext = systemUIContext,
+ systemUiContext = systemUiContext,
)
} else null
@@ -735,7 +728,7 @@
) {
logger.logAsyncTaskProgress(entry, "inflating public single line view model")
SingleLineViewInflater.inflateRedactedSingleLineViewModel(
- systemUIContext,
+ systemUiContext,
entry.ranking.isConversation,
)
} else null
@@ -761,12 +754,50 @@
)
}
+ private fun createSensitiveContentMessageNotification(
+ original: Notification,
+ originalStyle: Notification.Style?,
+ sysUiContext: Context,
+ packageContext: Context,
+ ): Notification.Builder {
+ val redacted = Notification.Builder(packageContext, original.channelId)
+ redacted.setContentTitle(original.extras.getCharSequence(Notification.EXTRA_TITLE))
+ val redactedMessage =
+ sysUiContext.getString(R.string.redacted_notification_single_line_text)
+
+ if (originalStyle is MessagingStyle) {
+ val newStyle = MessagingStyle(originalStyle.user)
+ newStyle.conversationTitle = originalStyle.conversationTitle
+ newStyle.isGroupConversation = false
+ newStyle.conversationType = originalStyle.conversationType
+ newStyle.shortcutIcon = originalStyle.shortcutIcon
+ newStyle.setBuilder(redacted)
+ val latestMessage = MessagingStyle.findLatestIncomingMessage(originalStyle.messages)
+ if (latestMessage != null) {
+ val newMessage =
+ MessagingStyle.Message(
+ redactedMessage,
+ latestMessage.timestamp,
+ latestMessage.senderPerson,
+ )
+ newStyle.addMessage(newMessage)
+ }
+ redacted.style = newStyle
+ } else {
+ redacted.setContentText(redactedMessage)
+ }
+ redacted.setLargeIcon(original.getLargeIcon())
+ redacted.setSmallIcon(original.smallIcon)
+ return redacted
+ }
+
private fun createRemoteViews(
@InflationFlag reInflateFlags: Int,
builder: Notification.Builder,
- isMinimized: Boolean,
- usesIncreasedHeight: Boolean,
- usesIncreasedHeadsUpHeight: Boolean,
+ bindParams: BindParams,
+ entry: NotificationEntry,
+ systemUiContext: Context,
+ packageContext: Context,
row: ExpandableNotificationRow,
notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
headsUpStyleProvider: HeadsUpStyleProvider,
@@ -780,7 +811,11 @@
entryForLogging,
"creating contracted remote view",
)
- createContentView(builder, isMinimized, usesIncreasedHeight)
+ createContentView(
+ builder,
+ bindParams.isMinimized,
+ bindParams.usesIncreasedHeight,
+ )
} else null
val expanded =
if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) {
@@ -788,7 +823,7 @@
entryForLogging,
"creating expanded remote view",
)
- createExpandedView(builder, isMinimized)
+ createExpandedView(builder, bindParams.isMinimized)
} else null
val headsUp =
if (reInflateFlags and FLAG_CONTENT_VIEW_HEADS_UP != 0) {
@@ -800,13 +835,26 @@
if (isHeadsUpCompact) {
builder.createCompactHeadsUpContentView()
} else {
- builder.createHeadsUpContentView(usesIncreasedHeadsUpHeight)
+ builder.createHeadsUpContentView(bindParams.usesIncreasedHeadsUpHeight)
}
} else null
val public =
if (reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC != 0) {
logger.logAsyncTaskProgress(entryForLogging, "creating public remote view")
- builder.makePublicContentView(isMinimized)
+ if (
+ LockscreenOtpRedaction.isEnabled &&
+ bindParams.redactionType == REDACTION_TYPE_SENSITIVE_CONTENT
+ ) {
+ createSensitiveContentMessageNotification(
+ entry.sbn.notification,
+ builder.style,
+ systemUiContext,
+ packageContext,
+ )
+ .createContentView(bindParams.usesIncreasedHeight)
+ } else {
+ builder.makePublicContentView(bindParams.isMinimized)
+ }
} else null
val normalGroupHeader =
if (
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java
index 427fb66..bc44cb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindParams.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.REDACTION_TYPE_NONE;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager.RedactionType;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
@@ -31,6 +33,7 @@
private boolean mUseIncreasedHeadsUpHeight;
private boolean mViewsNeedReinflation;
private @InflationFlag int mContentViews = DEFAULT_INFLATION_FLAGS;
+ private @RedactionType int mRedactionType = REDACTION_TYPE_NONE;
/**
* Content views that are out of date and need to be rebound.
@@ -58,6 +61,20 @@
}
/**
+ * @return What type of redaction should be used by the public view (if requested)
+ */
+ public @RedactionType int getRedactionType() {
+ return mRedactionType;
+ }
+
+ /**
+ * Set the redaction type, which controls what sort of public view is shown.
+ */
+ public void setRedactionType(@RedactionType int redactionType) {
+ mRedactionType = redactionType;
+ }
+
+ /**
* Set whether content should use an increased height version of its contracted view.
*/
public void setUseIncreasedCollapsedHeight(boolean useIncreasedHeight) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
index 89fcda9..53f7416 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStage.java
@@ -72,10 +72,8 @@
// Bind/unbind with parameters
mBinder.unbindContent(entry, row, contentToUnbind);
- BindParams bindParams = new BindParams();
- bindParams.isMinimized = params.useMinimized();
- bindParams.usesIncreasedHeight = params.useIncreasedHeight();
- bindParams.usesIncreasedHeadsUpHeight = params.useIncreasedHeadsUpHeight();
+ BindParams bindParams = new BindParams(params.useMinimized(), params.useIncreasedHeight(),
+ params.useIncreasedHeadsUpHeight(), params.getRedactionType());
boolean forceInflate = params.needsReinflation();
InflationCallback inflationCallback = new InflationCallback() {