diff options
author | Matías Hernández <matiashe@google.com> | 2024-03-22 14:26:23 +0100 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-05-02 10:44:42 +0000 |
commit | 01ae6dca58d6d7cfeae984b80511f62783317650 (patch) | |
tree | fee5a34f77eb52f416eb3049e6ec86abbc0b7bc5 | |
parent | 857af3fb7db9bf75e8a86af13018f99c0966cde5 (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
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); + } } |