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

Commit 99e9f0dc authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Use app uids in DndRule proto pulled atom"

parents d880d060 2beaf386
Loading
Loading
Loading
Loading
+38 −14
Original line number Diff line number Diff line
@@ -88,7 +88,6 @@ import libcore.io.IoUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.io.PrintWriter;
@@ -106,6 +105,9 @@ public class ZenModeHelper {
    // The amount of time rules instances can exist without their owning app being installed.
    private static final int RULE_INSTANCE_GRACE_PERIOD = 1000 * 60 * 60 * 72;

    // pkg|userId => uid
    protected final ArrayMap<String, Integer> mRulesUidCache = new ArrayMap<>();

    private final Context mContext;
    private final H mHandler;
    private final SettingsObserver mSettingsObserver;
@@ -384,17 +386,25 @@ public class ZenModeHelper {
        synchronized (mConfig) {
            if (mConfig == null) return false;
            newConfig = mConfig.copy();
            ZenRule rule = newConfig.automaticRules.get(id);
            if (rule == null) return false;
            if (canManageAutomaticZenRule(rule)) {
            ZenRule ruleToRemove = newConfig.automaticRules.get(id);
            if (ruleToRemove == null) return false;
            if (canManageAutomaticZenRule(ruleToRemove)) {
                newConfig.automaticRules.remove(id);
                if (ruleToRemove.pkg != null && !"android".equals(ruleToRemove.pkg)) {
                    for (ZenRule currRule : newConfig.automaticRules.values()) {
                        if (currRule.pkg != null && currRule.pkg.equals(ruleToRemove.pkg)) {
                            break; // no need to remove from cache
                        }
                    }
                    mRulesUidCache.remove(getPackageUserKey(ruleToRemove.pkg, newConfig.user));
                }
                if (DEBUG) Log.d(TAG, "removeZenRule zenRule=" + id + " reason=" + reason);
            } else {
                throw new SecurityException(
                        "Cannot delete rules not owned by your condition provider");
            }
            dispatchOnAutomaticRuleStatusChanged(
                    mConfig.user, rule.pkg, id, AUTOMATIC_RULE_STATUS_REMOVED);
                    mConfig.user, ruleToRemove.pkg, id, AUTOMATIC_RULE_STATUS_REMOVED);
            return setConfigLocked(newConfig, reason, null, true);
        }
    }
@@ -1192,7 +1202,6 @@ public class ZenModeHelper {
    public void pullRules(List<StatsEvent> events) {
        synchronized (mConfig) {
            final int numConfigs = mConfigs.size();
            int id = 0;
            for (int i = 0; i < numConfigs; i++) {
                final int user = mConfigs.keyAt(i);
                final ZenModeConfig config = mConfigs.valueAt(i);
@@ -1208,16 +1217,16 @@ public class ZenModeHelper {
                        .writeByteArray(config.toZenPolicy().toProto());
                events.add(data.build());
                if (config.manualRule != null && config.manualRule.enabler != null) {
                    ruleToProto(user, config.manualRule, events);
                    ruleToProtoLocked(user, config.manualRule, events);
                }
                for (ZenRule rule : config.automaticRules.values()) {
                    ruleToProto(user, rule, events);
                    ruleToProtoLocked(user, rule, events);
                }
            }
        }
    }

    private void ruleToProto(int user, ZenRule rule, List<StatsEvent> events) {
    private void ruleToProtoLocked(int user, ZenRule rule, List<StatsEvent> events) {
        // Make the ID safe.
        String id = rule.id == null ? "" : rule.id;
        if (!ZenModeConfig.DEFAULT_RULE_IDS.contains(id)) {
@@ -1231,9 +1240,6 @@ public class ZenModeHelper {
            id = ZenModeConfig.MANUAL_RULE_ID;
        }

        // TODO: fetch the uid from the package manager
        int uid = "android".equals(pkg) ? Process.SYSTEM_UID : 0;

        SysUiStatsEvent.Builder data;
        data = mStatsEventBuilderFactory.newBuilder()
                .setAtomId(DND_MODE_RULE)
@@ -1242,7 +1248,7 @@ public class ZenModeHelper {
                .writeBoolean(false) // channels_bypassing unused for rules
                .writeInt(rule.zenMode)
                .writeString(id)
                .writeInt(uid)
                .writeInt(getPackageUid(pkg, user))
                .addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
        byte[] policyProto = new byte[]{};
        if (rule.zenPolicy != null) {
@@ -1252,6 +1258,24 @@ public class ZenModeHelper {
        events.add(data.build());
    }

    private int getPackageUid(String pkg, int user) {
        if ("android".equals(pkg)) {
            return Process.SYSTEM_UID;
        }
        final String key = getPackageUserKey(pkg, user);
        if (mRulesUidCache.get(key) == null) {
            try {
                mRulesUidCache.put(key, mPm.getPackageUidAsUser(pkg, user));
            } catch (PackageManager.NameNotFoundException e) {
            }
        }
        return mRulesUidCache.getOrDefault(key, -1);
    }

    private static String getPackageUserKey(String pkg, int user) {
        return pkg + "|" + user;
    }

    @VisibleForTesting
    protected final class RingerModeDelegate implements AudioManagerInternal.RingerModeDelegate {
        @Override
+61 −10
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -101,7 +102,6 @@ import android.util.Xml;

import com.android.internal.R;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.UiServiceTestCase;
import com.android.server.notification.ManagedServices.UserProfiles;

@@ -110,9 +110,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -134,9 +132,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
    private static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE";
    private static final String SCHEDULE_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE";
    private static final int ZEN_MODE_FOR_TESTING = 99;
    private static final String CUSTOM_PKG_NAME = "not.android";
    private static final int CUSTOM_PKG_UID = 1;
    private static final String CUSTOM_RULE_ID = "custom_rule";

    ConditionProviders mConditionProviders;
    @Mock NotificationManager mNotificationManager;
    @Mock PackageManager mPackageManager;
    private Resources mResources;
    private TestableLooper mTestableLooper;
    private ZenModeHelper mZenModeHelperSpy;
@@ -146,7 +148,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
    private WrappedSysUiStatsEvent.WrappedBuilderFactory mStatsEventBuilderFactory;

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

        mTestableLooper = TestableLooper.get(this);
@@ -169,6 +171,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        mConditionProviders.addSystemProvider(new CountdownConditionProvider());
        mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
                mConditionProviders, mStatsEventBuilderFactory));

        when(mPackageManager.getPackageUidAsUser(eq(CUSTOM_PKG_NAME), anyInt()))
                .thenReturn(CUSTOM_PKG_UID);
        mZenModeHelperSpy.mPm = mPackageManager;
    }

    private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException {
@@ -238,19 +244,24 @@ public class ZenModeHelperTest extends UiServiceTestCase {

    private ArrayMap<String, ZenModeConfig.ZenRule> getCustomAutomaticRules(int zenMode) {
        ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
        ZenModeConfig.ZenRule rule = createCustomAutomaticRule(zenMode, CUSTOM_RULE_ID);
        automaticRules.put(rule.id, rule);
        return automaticRules;
    }

    private ZenModeConfig.ZenRule createCustomAutomaticRule(int zenMode, String id) {
        ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
        final ScheduleInfo customRuleInfo = new ScheduleInfo();
        customRule.enabled = true;
        customRule.creationTime = 0;
        customRule.id = "customRule";
        customRule.name = "Custom Rule";
        customRule.id = id;
        customRule.name = "Custom Rule with id=" + id;
        customRule.zenMode = zenMode;
        customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
        customRule.configurationActivity =
                new ComponentName("not.android", "ScheduleConditionProvider");
                new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider");
        customRule.pkg = customRule.configurationActivity.getPackageName();
        automaticRules.put("customRule", customRule);
        return automaticRules;
        return customRule;
    }

    @Test
@@ -893,7 +904,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
            if (builder.getAtomId() == DND_MODE_RULE) {
                if (ZEN_MODE_FOR_TESTING == builder.getInt(ZEN_MODE_FIELD_NUMBER)) {
                    foundCustomEvent = true;
                    assertEquals(0, builder.getInt(UID_FIELD_NUMBER));
                    assertEquals(CUSTOM_PKG_UID, builder.getInt(UID_FIELD_NUMBER));
                    assertTrue(builder.getBoolean(ENABLED_FIELD_NUMBER));
                }
            } else {
@@ -903,6 +914,46 @@ public class ZenModeHelperTest extends UiServiceTestCase {
        assertTrue("couldn't find custom rule", foundCustomEvent);
    }

    @Test
    public void ruleUidsCached() throws Exception {
        setupZenConfig();
        // one enabled automatic rule
        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
        List<StatsEvent> events = new LinkedList<>();
        // first time retrieving uid:
        mZenModeHelperSpy.pullRules(events);
        verify(mPackageManager, atLeastOnce()).getPackageUidAsUser(anyString(), anyInt());

        // second time retrieving uid:
        reset(mPackageManager);
        mZenModeHelperSpy.pullRules(events);
        verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());

        // new rule from same package + user added
        reset(mPackageManager);
        ZenModeConfig.ZenRule rule = createCustomAutomaticRule(ZEN_MODE_IMPORTANT_INTERRUPTIONS,
                CUSTOM_RULE_ID + "2");
        mZenModeHelperSpy.mConfig.automaticRules.put(rule.id, rule);
        mZenModeHelperSpy.pullRules(events);
        verify(mPackageManager, never()).getPackageUidAsUser(anyString(), anyInt());
    }

    @Test
    public void ruleUidAutomaticZenRuleRemovedUpdatesCache() throws Exception {
        when(mContext.checkCallingPermission(anyString()))
                .thenReturn(PackageManager.PERMISSION_GRANTED);

        setupZenConfig();
        // one enabled automatic rule
        mZenModeHelperSpy.mConfig.automaticRules = getCustomAutomaticRules();
        List<StatsEvent> events = new LinkedList<>();

        mZenModeHelperSpy.pullRules(events);
        mZenModeHelperSpy.removeAutomaticZenRule(CUSTOM_RULE_ID, "test");
        assertTrue(-1
                == mZenModeHelperSpy.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
    }

    @Test
    public void testProtoRedactsIds() throws Exception {
        setupZenConfig();