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

Commit 0044ab53 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Match any user pkgs for headless sys user mode"

parents 5a7e4de2 19eb2d59
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -10700,10 +10701,18 @@ public class NotificationManagerService extends SystemService {
        private final ArraySet<ManagedServiceInfo> mLightTrimListeners = new ArraySet<>();
        ArrayMap<Pair<ComponentName, Integer>, NotificationListenerFilter>
                mRequestedNotificationListeners = new ArrayMap<>();
        private final boolean mIsHeadlessSystemUserMode;
        public NotificationListeners(Context context, Object lock, UserProfiles userProfiles,
                IPackageManager pm) {
            this(context, lock, userProfiles, pm, UserManager.isHeadlessSystemUserMode());
        }
        @VisibleForTesting
        public NotificationListeners(Context context, Object lock, UserProfiles userProfiles,
                IPackageManager pm, boolean isHeadlessSystemUserMode) {
            super(context, lock, userProfiles, pm);
            this.mIsHeadlessSystemUserMode = isHeadlessSystemUserMode;
        }
        @Override
@@ -10728,10 +10737,16 @@ public class NotificationManagerService extends SystemService {
                    if (TextUtils.isEmpty(listeners[i])) {
                        continue;
                    }
                    int packageQueryFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
                    // In the headless system user mode, packages might not be installed for the
                    // system user. Match packages for any user since apps can be installed only for
                    // non-system users and would be considering uninstalled for the system user.
                    if (mIsHeadlessSystemUserMode) {
                        packageQueryFlags += MATCH_ANY_USER;
                    }
                    ArraySet<ComponentName> approvedListeners =
                            this.queryPackageForServices(listeners[i],
                                    MATCH_DIRECT_BOOT_AWARE
                                            | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM);
                            this.queryPackageForServices(listeners[i], packageQueryFlags,
                                    USER_SYSTEM);
                    for (int k = 0; k < approvedListeners.size(); k++) {
                        ComponentName cn = approvedListeners.valueAt(k);
                        addDefaultComponentOrPackage(cn.flattenToString());
+56 −3
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.server.notification;

import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
@@ -30,9 +31,11 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.intThat;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -49,6 +52,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.pm.VersionedPackage;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.NotificationListenerFilter;
@@ -69,6 +73,7 @@ import com.google.common.collect.ImmutableList;

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.internal.util.reflection.FieldSetter;
@@ -77,6 +82,7 @@ import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.List;

public class NotificationListenersTest extends UiServiceTestCase {
@@ -85,6 +91,8 @@ public class NotificationListenersTest extends UiServiceTestCase {
    private PackageManager mPm;
    @Mock
    private IPackageManager miPm;
    @Mock
    private Resources mResources;

    @Mock
    NotificationManagerService mNm;
@@ -96,7 +104,8 @@ public class NotificationListenersTest extends UiServiceTestCase {

    private ComponentName mCn1 = new ComponentName("pkg", "pkg.cmp");
    private ComponentName mCn2 = new ComponentName("pkg2", "pkg2.cmp2");

    private ComponentName mUninstalledComponent = new ComponentName("pkg3",
            "pkg3.NotificationListenerService");

    @Before
    public void setUp() throws Exception {
@@ -130,6 +139,50 @@ public class NotificationListenersTest extends UiServiceTestCase {
        validateListenersFromXml();
    }

    @Test
    public void loadDefaultsFromConfig_forHeadlessSystemUser_loadUninstalled() throws Exception {
        // setup with headless system user mode
        mListeners = spy(mNm.new NotificationListeners(
                mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm,
                /* isHeadlessSystemUserMode= */ true));
        mockDefaultListenerConfigForUninstalledComponent(mUninstalledComponent);

        mListeners.loadDefaultsFromConfig();

        assertThat(mListeners.getDefaultComponents()).contains(mUninstalledComponent);
    }

    @Test
    public void loadDefaultsFromConfig_forNonHeadlessSystemUser_ignoreUninstalled()
            throws Exception {
        // setup without headless system user mode
        mListeners = spy(mNm.new NotificationListeners(
                mContext, new Object(), mock(ManagedServices.UserProfiles.class), miPm,
                /* isHeadlessSystemUserMode= */ false));
        mockDefaultListenerConfigForUninstalledComponent(mUninstalledComponent);

        mListeners.loadDefaultsFromConfig();

        assertThat(mListeners.getDefaultComponents()).doesNotContain(mUninstalledComponent);
    }

    private void mockDefaultListenerConfigForUninstalledComponent(ComponentName componentName) {
        ArraySet<ComponentName> components = new ArraySet<>(Arrays.asList(componentName));
        when(mResources
                .getString(
                        com.android.internal.R.string.config_defaultListenerAccessPackages))
                .thenReturn(componentName.getPackageName());
        when(mContext.getResources()).thenReturn(mResources);
        doReturn(components).when(mListeners).queryPackageForServices(
                eq(componentName.getPackageName()),
                intThat(hasIntBitFlag(MATCH_ANY_USER)),
                anyInt());
    }

    public static ArgumentMatcher<Integer> hasIntBitFlag(int flag) {
        return arg -> arg != null && ((arg & flag) == flag);
    }

    @Test
    public void testWriteExtraTag() throws Exception {
        NotificationListenerFilter nlf = new NotificationListenerFilter(7, new ArraySet<>());