Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 878ba923 authored by Nicolò Mazzucato's avatar Nicolò Mazzucato Committed by Android (Google) Code Review
Browse files

Merge "Fix Notification inflation on secondary displays" into main

parents 17586613 5e1e59ac
Loading
Loading
Loading
Loading
+50 −13
Original line number Diff line number Diff line
@@ -30,13 +30,17 @@ import android.metrics.LogMaker;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
import android.os.UserHandle;
import android.util.ArrayMap;

import com.android.internal.logging.InstanceId;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import static com.android.window.flags.Flags.enablePerDisplayPackageContextCacheInStatusbarNotif;

import java.util.ArrayList;
import java.util.Map;

/**
 * Class encapsulating a Notification. Sent by the NotificationManagerService to clients including
@@ -69,7 +73,15 @@ public class StatusBarNotification implements Parcelable {
    // A small per-notification ID, used for statsd logging.
    private InstanceId mInstanceId;  // Not final, see setInstanceId()

    /**
     * @deprecated This field is only used when
     * {@link enablePerDisplayPackageContextCacheInStatusbarNotif}
     * is disabled.
     */
    @Deprecated
    private Context mContext; // used for inflation & icon expansion
    // Maps display id to context used for remote view content inflation and status bar icon.
    private final Map<Integer, Context> mContextForDisplayId = new ArrayMap<>();

    /** @hide */
    public StatusBarNotification(String pkg, String opPkg, int id,
@@ -453,8 +465,12 @@ public class StatusBarNotification implements Parcelable {
     * @hide
     */
    public void clearPackageContext() {
        if (enablePerDisplayPackageContextCacheInStatusbarNotif()) {
            mContextForDisplayId.clear();
        } else {
            mContext = null;
        }
    }

    /**
     * @hide
@@ -475,10 +491,16 @@ public class StatusBarNotification implements Parcelable {
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public Context getPackageContext(Context context) {
        if (enablePerDisplayPackageContextCacheInStatusbarNotif()) {
            if (context == null) return null;
            return mContextForDisplayId.computeIfAbsent(context.getDisplayId(),
                    (displayId) -> createPackageContext(context));
        } else {
            if (mContext == null) {
                try {
                    ApplicationInfo ai = context.getPackageManager()
                        .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
                            .getApplicationInfoAsUser(pkg,
                                    PackageManager.MATCH_UNINSTALLED_PACKAGES,
                                    getNormalizedUserId());
                    mContext = context.createApplicationContext(ai,
                            Context.CONTEXT_RESTRICTED);
@@ -491,6 +513,21 @@ public class StatusBarNotification implements Parcelable {
            }
            return mContext;
        }
    }

    private Context createPackageContext(Context context) {
        try {
            Trace.beginSection("StatusBarNotification#createPackageContext");
            ApplicationInfo ai = context.getPackageManager()
                    .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
                            getNormalizedUserId());
            return context.createApplicationContext(ai, Context.CONTEXT_RESTRICTED);
        } catch (PackageManager.NameNotFoundException e) {
            return context;
        } finally {
            Trace.endSection();
        }
    }

    /**
     * Returns a LogMaker that contains all basic information of the notification.
+10 −0
Original line number Diff line number Diff line
@@ -530,6 +530,16 @@ flag {
    bug: "381935663"
}

flag {
    name: "enable_per_display_package_context_cache_in_statusbar_notif"
    namespace: "lse_desktop_experience"
    description: "Enables per-display package context caching in StatusBarNotification"
    bug: "388886443"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "enable_desktop_wallpaper_activity_for_system_user"
    namespace: "lse_desktop_experience"
+33 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertNull;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -35,14 +36,19 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.metrics.LogMaker;
import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.view.Display;

import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.window.flags.Flags;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -52,11 +58,16 @@ import org.mockito.MockitoAnnotations;
@SmallTest
public class StatusBarNotificationTest {

    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private final Context mMockContext = mock(Context.class);
    @Mock
    private Context mRealContext;
    @Mock
    private PackageManager mPm;
    @Mock
    private Context mSecondaryDisplayContext;

    private static final String PKG = "com.example.o";
    private static final int UID = 9583;
@@ -80,6 +91,10 @@ public class StatusBarNotificationTest {
                InstrumentationRegistry.getContext().getResources());
        when(mMockContext.getPackageManager()).thenReturn(mPm);
        when(mMockContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
        when(mMockContext.getDisplayId()).thenReturn(Display.DEFAULT_DISPLAY);
        when(mSecondaryDisplayContext.getPackageManager()).thenReturn(mPm);
        when(mSecondaryDisplayContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
        when(mSecondaryDisplayContext.getDisplayId()).thenReturn(2);
        when(mPm.getApplicationLabel(any())).thenReturn("");

        mRealContext = InstrumentationRegistry.getContext();
@@ -220,6 +235,24 @@ public class StatusBarNotificationTest {
        assertEquals(pkg, resultContext.getPackageName());
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_PER_DISPLAY_PACKAGE_CONTEXT_CACHE_IN_STATUSBAR_NOTIF)
    public void testGetPackageContext_multipleDisplaysCase() {
        String pkg = "com.android.systemui";
        int uid = 1000;
        Notification notification = getNotificationBuilder(GROUP_ID_1, CHANNEL_ID).build();
        StatusBarNotification sbn = new StatusBarNotification(
                pkg, pkg, ID, TAG, uid, uid, notification, UserHandle.ALL, null, UID);
        Context defaultContext = sbn.getPackageContext(mRealContext);
        Context secondaryContext = sbn.getPackageContext(mSecondaryDisplayContext);
        assertNotSame(mRealContext, defaultContext);
        assertNotSame(defaultContext, secondaryContext);

        // Let's make sure it caches it:
        assertSame(defaultContext, sbn.getPackageContext(mRealContext));
        assertSame(secondaryContext, sbn.getPackageContext(mSecondaryDisplayContext));
    }

    @Test
    public void testGetUidFromKey() {
        StatusBarNotification sbn = getNotification("pkg", null, "channel");