Merge "Use app uids in DndRule proto pulled atom"
This commit is contained in:
@@ -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;
|
||||
@@ -145,7 +147,7 @@ public class ZenModeHelper {
|
||||
mHandler = new H(looper);
|
||||
addCallback(mMetrics);
|
||||
mAppOps = context.getSystemService(AppOpsManager.class);
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
|
||||
mDefaultConfig = readDefaultConfig(mContext.getResources());
|
||||
updateDefaultAutomaticRuleNames();
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user