summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatías Hernández <matiashe@google.com>2024-03-22 14:26:23 +0100
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-02 10:44:42 +0000
commit01ae6dca58d6d7cfeae984b80511f62783317650 (patch)
treefee5a34f77eb52f416eb3049e6ec86abbc0b7bc5
parent857af3fb7db9bf75e8a86af13018f99c0966cde5 (diff)
Resolve message/conversation image Uris with the correct user id
Bug: 317503801 Test: atest ExpandableNotificationRowTest (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:44524f06f9d652c596d542e0882eb2f17594f154) Merged-In: I11c5b39f2d9d8f0788acab43640a6d4abcd5a179 Change-Id: I11c5b39f2d9d8f0788acab43640a6d4abcd5a179
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java17
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java22
6 files changed, 129 insertions, 15 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 9f397fe9ac0c..85708394b09c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -40,6 +40,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Trace;
+import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -371,7 +372,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private boolean mUseIncreasedHeadsUpHeight;
private float mTranslationWhenRemoved;
private boolean mWasChildInGroupWhenRemoved;
- private NotificationInlineImageResolver mImageResolver;
+ private final NotificationInlineImageResolver mImageResolver;
@Nullable
private OnExpansionChangedListener mExpansionChangedListener;
@Nullable
@@ -1630,13 +1631,41 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
/**
- * Constructs an ExpandableNotificationRow.
- * @param context context passed to image resolver
+ * Constructs an ExpandableNotificationRow. Used by layout inflation.
+ *
+ * @param context passed to image resolver
* @param attrs attributes used to initialize parent view
*/
public ExpandableNotificationRow(Context context, AttributeSet attrs) {
- super(context, attrs);
- mImageResolver = new NotificationInlineImageResolver(context,
+ this(context, attrs, context);
+ Log.wtf(TAG, "This constructor shouldn't be called");
+ }
+
+ /**
+ * Constructs an ExpandableNotificationRow. Used by layout inflation (with a custom {@code
+ * AsyncLayoutFactory} in {@link RowInflaterTask}.
+ *
+ * @param context context context of the view
+ * @param attrs attributes used to initialize parent view
+ * @param entry notification that the row will be associated to (determines the user for the
+ * ImageResolver)
+ */
+ public ExpandableNotificationRow(Context context, AttributeSet attrs, NotificationEntry entry) {
+ this(context, attrs, userContextForEntry(context, entry));
+ }
+
+ private static Context userContextForEntry(Context base, NotificationEntry entry) {
+ if (base.getUserId() == entry.getSbn().getNormalizedUserId()) {
+ return base;
+ }
+ return base.createContextAsUser(
+ UserHandle.of(entry.getSbn().getNormalizedUserId()), /* flags= */ 0);
+ }
+
+ private ExpandableNotificationRow(Context sysUiContext, AttributeSet attrs,
+ Context userContext) {
+ super(sysUiContext, attrs);
+ mImageResolver = new NotificationInlineImageResolver(userContext,
new NotificationInlineImageCache());
float radius = getResources().getDimension(R.dimen.notification_corner_radius_small);
mSmallRoundness = radius / getMaxRadius();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
index c620f448b3b7..3e932aa616b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
@@ -66,7 +66,7 @@ public class NotificationInlineImageResolver implements ImageResolver {
* @param imageCache The implementation of internal cache.
*/
public NotificationInlineImageResolver(Context context, ImageCache imageCache) {
- mContext = context.getApplicationContext();
+ mContext = context;
mImageCache = imageCache;
if (mImageCache != null) {
@@ -76,6 +76,11 @@ public class NotificationInlineImageResolver implements ImageResolver {
updateMaxImageSizes();
}
+ @VisibleForTesting
+ public Context getContext() {
+ return mContext;
+ }
+
/**
* Check if this resolver has its internal cache implementation.
* @return True if has its internal cache, false otherwise.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
index 6feffe654630..b2fe1d82945b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java
@@ -17,10 +17,15 @@
package com.android.systemui.statusbar.notification.row;
import android.content.Context;
+import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.asynclayoutinflater.view.AsyncLayoutFactory;
import androidx.asynclayoutinflater.view.AsyncLayoutInflater;
import com.android.systemui.R;
@@ -55,12 +60,39 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf
mInflateOrigin = new Throwable("inflate requested here");
}
mListener = listener;
- AsyncLayoutInflater inflater = new AsyncLayoutInflater(context);
+ AsyncLayoutInflater inflater = new AsyncLayoutInflater(context,
+ new RowAsyncLayoutInflater(entry));
mEntry = entry;
entry.setInflationTask(this);
inflater.inflate(R.layout.status_bar_notification_row, parent, this);
}
+ @VisibleForTesting
+ static class RowAsyncLayoutInflater implements AsyncLayoutFactory {
+ private final NotificationEntry mEntry;
+
+ RowAsyncLayoutInflater(NotificationEntry entry) {
+ mEntry = entry;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@Nullable View parent, @NonNull String name,
+ @NonNull Context context, @NonNull AttributeSet attrs) {
+ if (name.equals(ExpandableNotificationRow.class.getName())) {
+ return new ExpandableNotificationRow(context, attrs, mEntry);
+ }
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull String name, @NonNull Context context,
+ @NonNull AttributeSet attrs) {
+ return null;
+ }
+ }
+
@Override
public void abort() {
mCancelled = true;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 4c83194783ab..35211ea2174e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -20,6 +20,8 @@ import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL;
+import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.PKG;
+import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.USER_HANDLE;
import static com.google.common.truth.Truth.assertThat;
@@ -40,10 +42,12 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.app.NotificationChannel;
+import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -56,6 +60,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.R;
import com.android.internal.widget.CachingIconView;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.SysuiTestableContext;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -733,6 +738,26 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
verify(lowPriVectorDrawable, times(1)).start();
}
+ @Test
+ public void imageResolver_sameNotificationUser_usesContext() throws Exception {
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(PKG,
+ USER_HANDLE.getUid(1234), USER_HANDLE);
+
+ assertThat(row.getImageResolver().getContext()).isSameInstanceAs(mContext);
+ }
+
+ @Test
+ public void imageResolver_differentNotificationUser_createsUserContext() throws Exception {
+ UserHandle user = new UserHandle(33);
+ Context userContext = new SysuiTestableContext(mContext);
+ mContext.prepareCreateContextAsUser(user, userContext);
+
+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(PKG,
+ user.getUid(1234), user);
+
+ assertThat(row.getImageResolver().getContext()).isSameInstanceAs(userContext);
+ }
+
private void setDrawableIconsInImageView(CachingIconView icon, Drawable iconDrawable,
Drawable rightIconDrawable) {
ImageView iconView = mock(ImageView.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 813bae893569..b4be92e86ff0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -526,14 +526,6 @@ public class NotificationTestHelper {
@InflationFlag int extraInflationFlags,
int importance)
throws Exception {
- LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
- mContext.LAYOUT_INFLATER_SERVICE);
- mRow = (ExpandableNotificationRow) inflater.inflate(
- R.layout.status_bar_notification_row,
- null /* root */,
- false /* attachToRoot */);
- ExpandableNotificationRow row = mRow;
-
final NotificationChannel channel =
new NotificationChannel(
notification.getChannelId(),
@@ -553,6 +545,15 @@ public class NotificationTestHelper {
.setChannel(channel)
.build();
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.setFactory2(new RowInflaterTask.RowAsyncLayoutInflater(entry));
+ mRow = (ExpandableNotificationRow) inflater.inflate(
+ R.layout.status_bar_notification_row,
+ null /* root */,
+ false /* attachToRoot */);
+ ExpandableNotificationRow row = mRow;
+
entry.setRow(row);
mIconManager.createIcons(entry);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
index 5ff57aad9f5d..aa58b89f4676 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java
@@ -14,6 +14,7 @@
package com.android.systemui;
+import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -29,12 +30,15 @@ import android.view.Display;
import com.android.internal.annotations.GuardedBy;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
public class SysuiTestableContext extends TestableContext {
@GuardedBy("mRegisteredReceivers")
private final Set<BroadcastReceiver> mRegisteredReceivers = new ArraySet<>();
+ private final Map<UserHandle, Context> mContextForUser = new HashMap<>();
public SysuiTestableContext(Context base) {
super(base);
@@ -152,4 +156,22 @@ public class SysuiTestableContext extends TestableContext {
}
super.unregisterReceiver(receiver);
}
+
+ /**
+ * Sets a Context object that will be returned as the result of {@link #createContextAsUser}
+ * for a specific {@code user}.
+ */
+ public void prepareCreateContextAsUser(UserHandle user, Context context) {
+ mContextForUser.put(user, context);
+ }
+
+ @Override
+ @NonNull
+ public Context createContextAsUser(UserHandle user, int flags) {
+ Context userContext = mContextForUser.get(user);
+ if (userContext != null) {
+ return userContext;
+ }
+ return super.createContextAsUser(user, flags);
+ }
}