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

Commit 76e1f272 authored by Jay Aliomer's avatar Jay Aliomer
Browse files

No notification actions

Upgraded users dont have their default services set.
To solve it, the managed services object looks at the user's
enabled components and sets them as default. otherwise, it fills the
defaults from the configuration xml

Fixes: 149835754
Test: all Notification services tests
Change-Id: I3fa4745c36808385924ec0c8a5137c8e701f91f6
parent 652a8a65
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.provider.Settings;
import android.service.notification.Condition;
import android.service.notification.ConditionProviderService;
import android.service.notification.IConditionProvider;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
@@ -54,7 +55,6 @@ public class ConditionProviders extends ManagedServices {
    private final ArraySet<String> mSystemConditionProviderNames;
    private final ArraySet<SystemConditionProviderService> mSystemConditionProviders
            = new ArraySet<>();

    private Callback mCallback;

    public ConditionProviders(Context context, UserProfiles userProfiles, IPackageManager pm) {
@@ -194,6 +194,21 @@ public class ConditionProviders extends ManagedServices {
        }
    }

    @Override
    protected void loadDefaultsFromConfig() {
        String defaultDndAccess = mContext.getResources().getString(
                R.string.config_defaultDndAccessPackages);
        if (defaultDndAccess != null) {
            String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
            for (int i = 0; i < dnds.length; i++) {
                if (TextUtils.isEmpty(dnds[i])) {
                    continue;
                }
                addDefaultComponentOrPackage(dnds[i]);
            }
        }
    }

    @Override
    protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
        if (removed == null) return;
+56 −17
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.DEVICE_POLICY_SERVICE;
import static android.os.UserHandle.USER_ALL;
import static android.os.UserHandle.USER_SYSTEM;

import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -96,6 +97,8 @@ abstract public class ManagedServices {

    private static final int ON_BINDING_DIED_REBIND_DELAY_MS = 10000;
    protected static final String ENABLED_SERVICES_SEPARATOR = ":";
    private static final String DB_VERSION_1 = "1";


    /**
     * List of components and apps that can have running {@link ManagedServices}.
@@ -107,7 +110,7 @@ abstract public class ManagedServices {
    static final String ATT_VERSION = "version";
    static final String ATT_DEFAULTS = "defaults";

    static final int DB_VERSION = 1;
    static final int DB_VERSION = 2;

    static final int APPROVAL_BY_PACKAGE = 0;
    static final int APPROVAL_BY_COMPONENT = 1;
@@ -187,17 +190,22 @@ abstract public class ManagedServices {
    protected void addDefaultComponentOrPackage(String packageOrComponent) {
        if (!TextUtils.isEmpty(packageOrComponent)) {
            synchronized (mDefaultsLock) {
                ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
                if (cn == null) {
                if (mApprovalLevel == APPROVAL_BY_PACKAGE) {
                    mDefaultPackages.add(packageOrComponent);
                } else {
                    return;
                }
                ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
                if (cn != null  && mApprovalLevel == APPROVAL_BY_COMPONENT) {
                    mDefaultPackages.add(cn.getPackageName());
                    mDefaultComponents.add(cn);
                    return;
                }
            }
        }
    }

    protected abstract void loadDefaultsFromConfig();

    boolean isDefaultComponentOrPackage(String packageOrComponent) {
        synchronized (mDefaultsLock) {
            ComponentName cn = ComponentName.unflattenFromString(packageOrComponent);
@@ -504,9 +512,8 @@ abstract public class ManagedServices {

    void readDefaults(XmlPullParser parser) {
        String defaultComponents = XmlUtils.readStringAttribute(parser, ATT_DEFAULTS);
        if (defaultComponents == null) {
            return;
        }

        if (!TextUtils.isEmpty(defaultComponents)) {
            String[] components = defaultComponents.split(ENABLED_SERVICES_SEPARATOR);
            synchronized (mDefaultsLock) {
                for (int i = 0; i < components.length; i++) {
@@ -522,6 +529,7 @@ abstract public class ManagedServices {
                }
            }
        }
    }

    public void readXml(
            XmlPullParser parser,
@@ -531,9 +539,11 @@ abstract public class ManagedServices {
            throws XmlPullParserException, IOException {
        // read grants
        int type;
        String version = "";
        readDefaults(parser);
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
            String tag = parser.getName();
            version = XmlUtils.readStringAttribute(parser, ATT_VERSION);
            if (type == XmlPullParser.END_TAG
                    && getConfig().xmlTag.equals(tag)) {
                break;
@@ -561,9 +571,38 @@ abstract public class ManagedServices {
                }
            }
        }
        boolean isVersionOne = TextUtils.isEmpty(version) || DB_VERSION_1.equals(version);
        if (isVersionOne) {
            upgradeToVersionTwo();
        }
        rebindServices(false, USER_ALL);
    }

    private void upgradeToVersionTwo() {
        // check if any defaults are loaded
        int defaultsSize = mDefaultComponents.size() + mDefaultPackages.size();
        if (defaultsSize == 0) {
            // load defaults from current allowed
            if (this.mApprovalLevel == APPROVAL_BY_COMPONENT) {
                List<ComponentName> approvedComponents = getAllowedComponents(USER_SYSTEM);
                for (int i = 0; i < approvedComponents.size(); i++) {
                    addDefaultComponentOrPackage(approvedComponents.get(i).flattenToString());
                }
            }
            if (this.mApprovalLevel == APPROVAL_BY_PACKAGE) {
                List<String> approvedPkgs = getAllowedPackages(USER_SYSTEM);
                for (int i = 0; i < approvedPkgs.size(); i++) {
                    addDefaultComponentOrPackage(approvedPkgs.get(i));
                }
            }
        }
        // if no defaults are loaded, then load from config
        defaultsSize = mDefaultComponents.size() + mDefaultPackages.size();
        if (defaultsSize == 0) {
            loadDefaultsFromConfig();
        }
    }

    /**
     * Read extra attributes in the {@link #TAG_MANAGED_SERVICES} tag.
     */
+52 −53
Original line number Diff line number Diff line
@@ -600,57 +600,11 @@ public class NotificationManagerService extends SystemService {
    }

    void loadDefaultApprovedServices(int userId) {
        String defaultListenerAccess = getContext().getResources().getString(
                com.android.internal.R.string.config_defaultListenerAccessPackages);
        if (defaultListenerAccess != null) {
            String[] listeners =
                    defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
            for (int i = 0; i < listeners.length; i++) {
                if (TextUtils.isEmpty(listeners[i])) {
                    continue;
                }
                ArraySet<ComponentName> approvedListeners =
                        mListeners.queryPackageForServices(listeners[i],
                                MATCH_DIRECT_BOOT_AWARE
                                        | MATCH_DIRECT_BOOT_UNAWARE, userId);
                for (int k = 0; k < approvedListeners.size(); k++) {
                    ComponentName cn = approvedListeners.valueAt(k);
                    mListeners.addDefaultComponentOrPackage(cn.flattenToString());
                }
            }
        }

        String defaultDndAccess = getContext().getResources().getString(
                com.android.internal.R.string.config_defaultDndAccessPackages);
        if (defaultDndAccess != null) {
            String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
            for (int i = 0; i < dnds.length; i++) {
                if (TextUtils.isEmpty(dnds[i])) {
                    continue;
                }
                mConditionProviders.addDefaultComponentOrPackage(dnds[i]);
            }
        }
        mListeners.loadDefaultsFromConfig();

        mConditionProviders.loadDefaultsFromConfig();

        ArraySet<String> assistants = new ArraySet<>();
        String deviceAssistant = DeviceConfig.getProperty(
                DeviceConfig.NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE);
        if (deviceAssistant != null) {
            assistants.addAll(Arrays.asList(deviceAssistant.split(
                    ManagedServices.ENABLED_SERVICES_SEPARATOR)));
        }
        assistants.addAll(Arrays.asList(getContext().getResources().getString(
                com.android.internal.R.string.config_defaultAssistantAccessComponent)
                .split(ManagedServices.ENABLED_SERVICES_SEPARATOR)));
        for (int i = 0; i < assistants.size(); i++) {
            String cnString = assistants.valueAt(i);
            if (TextUtils.isEmpty(cnString)) {
                continue;
            }
            mAssistants.addDefaultComponentOrPackage(cnString);
        }
        mAssistants.loadDefaultsFromConfig();
    }

    protected void allowDefaultApprovedServices(int userId) {
@@ -673,11 +627,14 @@ public class NotificationManagerService extends SystemService {
                DeviceConfig.NAMESPACE_SYSTEMUI,
                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE);
        if (overrideDefaultAssistantString != null) {
            ComponentName overrideDefaultAssistant =
                    ComponentName.unflattenFromString(overrideDefaultAssistantString);
            if (allowAssistant(userId, overrideDefaultAssistant)) return;
            ArraySet<ComponentName> approved = mAssistants.queryPackageForServices(
                    overrideDefaultAssistantString,
                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                    userId);
            for (int i = 0; i < approved.size(); i++) {
                if (allowAssistant(userId, approved.valueAt(i))) return;
            }
        }

        ArraySet<ComponentName> defaults = mAssistants.getDefaultComponents();
        // We should have only one default assistant by default
        // allowAssistant should execute once in practice
@@ -8602,6 +8559,26 @@ public class NotificationManagerService extends SystemService {
        private ArrayMap<Integer, Boolean> mUserSetMap = new ArrayMap<>();
        private Set<String> mAllowedAdjustments = new ArraySet<>();

        @Override
        protected void loadDefaultsFromConfig() {
            ArraySet<String> assistants = new ArraySet<>();
            assistants.addAll(Arrays.asList(mContext.getResources().getString(
                    com.android.internal.R.string.config_defaultAssistantAccessComponent)
                    .split(ManagedServices.ENABLED_SERVICES_SEPARATOR)));
            for (int i = 0; i < assistants.size(); i++) {
                String cnString = assistants.valueAt(i);
                if (TextUtils.isEmpty(cnString)) {
                    continue;
                }
                ArraySet<ComponentName> approved = queryPackageForServices(cnString,
                        MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM);
                for (int k = 0; k < approved.size(); k++) {
                    ComponentName cn = approved.valueAt(k);
                    addDefaultComponentOrPackage(cn.flattenToString());
                }
            }
        }

        public NotificationAssistants(Context context, Object lock, UserProfiles up,
                IPackageManager pm) {
            super(context, lock, up, pm);
@@ -9039,7 +9016,29 @@ public class NotificationManagerService extends SystemService {

        public NotificationListeners(IPackageManager pm) {
            super(getContext(), mNotificationLock, mUserProfiles, pm);
        }

        @Override
        protected void loadDefaultsFromConfig() {
            String defaultListenerAccess = mContext.getResources().getString(
                    R.string.config_defaultListenerAccessPackages);
            if (defaultListenerAccess != null) {
                String[] listeners =
                        defaultListenerAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
                for (int i = 0; i < listeners.length; i++) {
                    if (TextUtils.isEmpty(listeners[i])) {
                        continue;
                    }
                    ArraySet<ComponentName> approvedListeners =
                            this.queryPackageForServices(listeners[i],
                                    MATCH_DIRECT_BOOT_AWARE
                                            | MATCH_DIRECT_BOOT_UNAWARE, USER_SYSTEM);
                    for (int k = 0; k < approvedListeners.size(); k++) {
                        ComponentName cn = approvedListeners.valueAt(k);
                        addDefaultComponentOrPackage(cn.flattenToString());
                    }
                }
            }
        }

        @Override
+111 −5
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -96,6 +97,10 @@ public class ManagedServicesTest extends UiServiceTestCase {

    UserInfo mZero = new UserInfo(0, "zero", 0);
    UserInfo mTen = new UserInfo(10, "ten", 0);
    private String mDefaultsString;
    private String mVersionString;
    private final Set<ComponentName> mDefaults = new ArraySet();
    private ManagedServices mService;

    private static final String SETTING = "setting";
    private static final String SECONDARY_SETTING = "secondary_setting";
@@ -106,8 +111,8 @@ public class ManagedServicesTest extends UiServiceTestCase {
    private ArrayMap<Integer, String> mExpectedSecondaryComponentNames;

    // type : user : list of approved
    private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary = new ArrayMap<>();
    private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary = new ArrayMap<>();
    private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedPrimary;
    private ArrayMap<Integer, ArrayMap<Integer, String>> mExpectedSecondary;

    @Before
    public void setUp() throws Exception {
@@ -132,6 +137,9 @@ public class ManagedServicesTest extends UiServiceTestCase {
        profileIds.add(12);
        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);

        mVersionString = "2";
        mExpectedPrimary = new ArrayMap<>();
        mExpectedSecondary = new ArrayMap<>();
        mExpectedPrimaryPackages = new ArrayMap<>();
        mExpectedPrimaryPackages.put(0, "this.is.a.package.name:another.package");
        mExpectedPrimaryPackages.put(10, "this.is.another.package");
@@ -155,6 +163,8 @@ public class ManagedServicesTest extends UiServiceTestCase {
                "this.is.another.package:component:package");
        mExpectedSecondary.put(APPROVAL_BY_PACKAGE, mExpectedSecondaryPackages);
        mExpectedSecondary.put(APPROVAL_BY_COMPONENT, mExpectedSecondaryComponentNames);
        mService = new TestManagedServices(getContext(), mLock, mUserProfiles,
                mIpm, APPROVAL_BY_COMPONENT);
    }

    @Test
@@ -1178,9 +1188,99 @@ public class ManagedServicesTest extends UiServiceTestCase {
        }
    }

    @Test
    public void loadDefaults_noVersionNoDefaults() throws Exception {
        resetComponentsAndPackages();
        loadXml(mService);
        assertEquals(mService.getDefaultComponents().size(), 0);
    }

    @Test
    public void loadDefaults_noVersionNoDefaultsOneActive() throws Exception {
        resetComponentsAndPackages();
        mService.addDefaultComponentOrPackage("package/class");
        loadXml(mService);
        assertEquals(1, mService.getDefaultComponents().size());
        assertTrue(mService.getDefaultComponents()
                .contains(ComponentName.unflattenFromString("package/class")));
    }

    @Test
    public void loadDefaults_noVersionWithDefaults() throws Exception {
        resetComponentsAndPackages();
        mDefaults.add(new ComponentName("default", "class"));
        loadXml(mService);
        assertEquals(mService.getDefaultComponents(), mDefaults);
    }

    @Test
    public void loadDefaults_versionOneWithDefaultsWithActive() throws Exception {
        resetComponentsAndPackages();
        mDefaults.add(new ComponentName("default", "class"));
        mExpectedPrimaryComponentNames.put(0, "package/class");
        mVersionString = "1";
        loadXml(mService);
        assertEquals(mService.getDefaultComponents(),
                new ArraySet(Arrays.asList(new ComponentName("package", "class"))));
    }

    @Test
    public void loadDefaults_versionTwoWithDefaultsWithActive() throws Exception {
        resetComponentsAndPackages();
        mDefaults.add(new ComponentName("default", "class"));
        mDefaultsString = "default/class";
        mExpectedPrimaryComponentNames.put(0, "package/class");
        mVersionString = "2";
        loadXml(mService);
        assertEquals(1, mService.getDefaultComponents().size());
        mDefaults.forEach(pkg -> {
            assertTrue(mService.getDefaultComponents().contains(pkg));
        });
    }

    @Test
    public void loadDefaults_versionOneWithXMLDefaultsWithActive() throws Exception {
        resetComponentsAndPackages();
        mDefaults.add(new ComponentName("default", "class"));
        mDefaultsString = "xml/class";
        mExpectedPrimaryComponentNames.put(0, "package/class");
        mVersionString = "1";
        loadXml(mService);
        assertEquals(mService.getDefaultComponents(),
                new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
    }

    @Test
    public void loadDefaults_versionTwoWithXMLDefaultsWithActive() throws Exception {
        resetComponentsAndPackages();
        mDefaults.add(new ComponentName("default", "class"));
        mDefaultsString = "xml/class";
        mExpectedPrimaryComponentNames.put(0, "package/class");
        mVersionString = "2";
        loadXml(mService);
        assertEquals(mService.getDefaultComponents(),
                new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
    }

    private void resetComponentsAndPackages() {
        ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1);
        ArrayMap<Integer, String> emptyPkgs = new ArrayMap(0);
        empty.append(mService.mApprovalLevel, emptyPkgs);
        mExpectedPrimary = empty;
        mExpectedPrimaryComponentNames = emptyPkgs;
        mExpectedPrimaryPackages = emptyPkgs;
        mExpectedSecondary = empty;
        mExpectedSecondaryComponentNames = emptyPkgs;
        mExpectedSecondaryPackages = emptyPkgs;
    }

    private void loadXml(ManagedServices service) throws Exception {
        final StringBuffer xml = new StringBuffer();
        xml.append("<" + service.getConfig().xmlTag + ">\n");
        String xmlTag = service.getConfig().xmlTag;
        xml.append("<" + xmlTag
                + (mDefaultsString != null ? " defaults=\"" + mDefaultsString + "\" " : "")
                + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "")
                + ">\n");
        for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
            xml.append(getXmlEntry(
                    mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true));
@@ -1197,7 +1297,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
                + ManagedServices.ATT_USER_ID + "=\"98\" "
                + ManagedServices.ATT_IS_PRIMARY + "=\"false\" "
                + ManagedServices.ATT_APPROVED_LIST + "=\"98\" />\n");
        xml.append("</" + service.getConfig().xmlTag + ">");
        xml.append("</" + xmlTag + ">");

        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new BufferedInputStream(
@@ -1224,6 +1324,7 @@ public class ManagedServicesTest extends UiServiceTestCase {

    private void addExpectedServices(final ManagedServices service, final List<String> packages,
            int userId) {
        ManagedServices.Config config = service.getConfig();
        when(mPm.queryIntentServicesAsUser(any(), anyInt(), eq(userId))).
                thenAnswer(new Answer<List<ResolveInfo>>() {
                    @Override
@@ -1233,7 +1334,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
                        Intent invocationIntent = (Intent) args[0];
                        if (invocationIntent != null) {
                            if (invocationIntent.getAction().equals(
                                    service.getConfig().serviceInterface)
                                    config.serviceInterface)
                                    && packages.contains(invocationIntent.getPackage())) {
                                List<ResolveInfo> dummyServices = new ArrayList<>();
                                for (int i = 1; i <= 3; i ++) {
@@ -1430,6 +1531,11 @@ public class ManagedServicesTest extends UiServiceTestCase {

        }

        @Override
        protected void loadDefaultsFromConfig() {
            mDefaultComponents.addAll(mDefaults);
        }

        @Override
        protected String getRequiredPermission() {
            return null;
+2 −2
Original line number Diff line number Diff line
@@ -72,13 +72,13 @@ public class NotificationAssistantsTest extends UiServiceTestCase {

    Object mLock = new Object();


    UserInfo mZero = new UserInfo(0, "zero", 0);
    UserInfo mTen = new UserInfo(10, "ten", 0);

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        getContext().setMockPackageManager(mPm);
        getContext().addMockSystemService(Context.USER_SERVICE, mUm);
        mAssistants = spy(mNm.new NotificationAssistants(getContext(), mLock, mUserProfiles, miPm));
@@ -122,7 +122,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {

    @Test
    public void testXmlUpgradeExistingApprovedComponents() throws Exception {
        String xml = "<enabled_assistants>"
        String xml = "<enabled_assistants version=\"2\" defaults=\"b\\b\">"
                + "<service_listing approved=\"b/b\" user=\"10\" primary=\"true\" />"
                + "</enabled_assistants>";

Loading