Merge "Add DND whitelist" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
aba783991a
@@ -3483,6 +3483,12 @@
|
||||
<item>com.android.messaging</item>
|
||||
</string-array>
|
||||
|
||||
<!-- An array of packages that can make sound on the ringer stream in priority-only DND
|
||||
mode -->
|
||||
<string-array translatable="false" name="config_priorityOnlyDndExemptPackages">
|
||||
<item>com.android.dialer</item>
|
||||
</string-array>
|
||||
|
||||
<!-- An array of packages which can listen for notifications on low ram devices. -->
|
||||
<string-array translatable="false" name="config_allowedManagedServicesOnLowRamDevices" />
|
||||
|
||||
|
||||
@@ -3188,6 +3188,7 @@
|
||||
<java-symbol type="array" name="config_convert_to_emergency_number_map" />
|
||||
|
||||
<java-symbol type="array" name="config_nonBlockableNotificationPackages" />
|
||||
<java-symbol type="array" name="config_priorityOnlyDndExemptPackages" />
|
||||
|
||||
<java-symbol type="array" name="config_allowedManagedServicesOnLowRamDevices" />
|
||||
|
||||
|
||||
@@ -1689,6 +1689,9 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray(
|
||||
com.android.internal.R.array.config_nonBlockableNotificationPackages));
|
||||
|
||||
mZenModeHelper.setPriorityOnlyDndExemptPackages(getContext().getResources().getStringArray(
|
||||
com.android.internal.R.array.config_priorityOnlyDndExemptPackages));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -80,6 +80,7 @@ import org.xmlpull.v1.XmlSerializer;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -96,7 +97,7 @@ public class ZenModeHelper {
|
||||
private final Context mContext;
|
||||
private final H mHandler;
|
||||
private final SettingsObserver mSettingsObserver;
|
||||
@VisibleForTesting protected final AppOpsManager mAppOps;
|
||||
private final AppOpsManager mAppOps;
|
||||
@VisibleForTesting protected final NotificationManager mNotificationManager;
|
||||
@VisibleForTesting protected ZenModeConfig mDefaultConfig;
|
||||
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
|
||||
@@ -123,11 +124,13 @@ public class ZenModeHelper {
|
||||
|
||||
@VisibleForTesting protected boolean mIsBootComplete;
|
||||
|
||||
private String[] mPriorityOnlyDndExemptPackages;
|
||||
|
||||
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
|
||||
mContext = context;
|
||||
mHandler = new H(looper);
|
||||
addCallback(mMetrics);
|
||||
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
|
||||
mAppOps = context.getSystemService(AppOpsManager.class);
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
|
||||
mDefaultConfig = readDefaultConfig(mContext.getResources());
|
||||
@@ -214,6 +217,10 @@ public class ZenModeHelper {
|
||||
loadConfigForUser(user, "onUserUnlocked");
|
||||
}
|
||||
|
||||
void setPriorityOnlyDndExemptPackages(String[] packages) {
|
||||
mPriorityOnlyDndExemptPackages = packages;
|
||||
}
|
||||
|
||||
private void loadConfigForUser(int user, String reason) {
|
||||
if (mUser == user || user < UserHandle.USER_SYSTEM) return;
|
||||
mUser = user;
|
||||
@@ -994,53 +1001,47 @@ public class ZenModeHelper {
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
final int suppressionBehavior = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage);
|
||||
if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_NEVER) {
|
||||
applyRestrictions(false /*mute*/, usage);
|
||||
applyRestrictions(zenPriorityOnly, false /*mute*/, usage);
|
||||
} else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_NOTIFICATION) {
|
||||
applyRestrictions(muteNotifications || muteEverything, usage);
|
||||
applyRestrictions(zenPriorityOnly, muteNotifications || muteEverything, usage);
|
||||
} else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_CALL) {
|
||||
applyRestrictions(muteCalls || muteEverything, usage);
|
||||
applyRestrictions(zenPriorityOnly, muteCalls || muteEverything, usage);
|
||||
} else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_ALARM) {
|
||||
applyRestrictions(muteAlarms || muteEverything, usage);
|
||||
applyRestrictions(zenPriorityOnly, muteAlarms || muteEverything, usage);
|
||||
} else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_MEDIA) {
|
||||
applyRestrictions(muteMedia || muteEverything, usage);
|
||||
applyRestrictions(zenPriorityOnly, muteMedia || muteEverything, usage);
|
||||
} else if (suppressionBehavior == AudioAttributes.SUPPRESSIBLE_SYSTEM) {
|
||||
if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
|
||||
// normally DND will only restrict touch sounds, not haptic feedback/vibrations
|
||||
applyRestrictions(muteSystem || muteEverything, usage,
|
||||
applyRestrictions(zenPriorityOnly, muteSystem || muteEverything, usage,
|
||||
AppOpsManager.OP_PLAY_AUDIO);
|
||||
applyRestrictions(false, usage, AppOpsManager.OP_VIBRATE);
|
||||
applyRestrictions(zenPriorityOnly, false, usage, AppOpsManager.OP_VIBRATE);
|
||||
} else {
|
||||
applyRestrictions(muteSystem || muteEverything, usage);
|
||||
applyRestrictions(zenPriorityOnly, muteSystem || muteEverything, usage);
|
||||
}
|
||||
} else {
|
||||
applyRestrictions(muteEverything, usage);
|
||||
applyRestrictions(zenPriorityOnly, muteEverything, usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
protected void applyRestrictions(boolean mute, int usage, int code) {
|
||||
final String[] exceptionPackages = null; // none (for now)
|
||||
|
||||
// Only do this if we are executing within the system process... otherwise
|
||||
// we are running as test code, so don't have access to the protected call.
|
||||
if (Process.myUid() == Process.SYSTEM_UID) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mAppOps.setRestriction(code, usage,
|
||||
mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
|
||||
exceptionPackages);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
protected void applyRestrictions(boolean zenPriorityOnly, boolean mute, int usage, int code) {
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mAppOps.setRestriction(code, usage,
|
||||
mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
|
||||
zenPriorityOnly ? mPriorityOnlyDndExemptPackages : null);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void applyRestrictions(boolean mute, int usage) {
|
||||
applyRestrictions(mute, usage, AppOpsManager.OP_VIBRATE);
|
||||
applyRestrictions(mute, usage, AppOpsManager.OP_PLAY_AUDIO);
|
||||
protected void applyRestrictions(boolean zenPriorityOnly, boolean mute, int usage) {
|
||||
applyRestrictions(zenPriorityOnly, mute, usage, AppOpsManager.OP_VIBRATE);
|
||||
applyRestrictions(zenPriorityOnly, mute, usage, AppOpsManager.OP_PLAY_AUDIO);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -349,6 +349,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
|
||||
when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
|
||||
when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
|
||||
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
|
||||
|
||||
// write to a test file; the system file isn't readable from tests
|
||||
mFile = new File(mContext.getCacheDir(), "test.xml");
|
||||
|
||||
@@ -206,6 +206,7 @@ public class RoleObserverTest extends UiServiceTestCase {
|
||||
|
||||
LocalServices.removeServiceForTest(WindowManagerInternal.class);
|
||||
LocalServices.addService(WindowManagerInternal.class, mock(WindowManagerInternal.class));
|
||||
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
|
||||
|
||||
mUsers = new ArrayList<>();
|
||||
mUsers.add(new UserInfo(0, "system", 0));
|
||||
|
||||
@@ -110,6 +110,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
private ZenModeHelper mZenModeHelperSpy;
|
||||
private Context mContext;
|
||||
private ContentResolver mContentResolver;
|
||||
@Mock AppOpsManager mAppOps;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -127,6 +128,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
e.toString());
|
||||
}
|
||||
|
||||
when(mContext.getSystemService(AppOpsManager.class)).thenReturn(mAppOps);
|
||||
when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
|
||||
mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
|
||||
AppGlobals.getPackageManager());
|
||||
@@ -219,10 +221,10 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
doNothing().when(mZenModeHelperSpy).applyRestrictions(anyBoolean(), anyInt());
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
doNothing().when(mZenModeHelperSpy).applyRestrictions(eq(false), anyBoolean(), anyInt());
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_ALARM);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_MEDIA);
|
||||
}
|
||||
|
||||
@@ -233,9 +235,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
Policy.PRIORITY_CATEGORY_MEDIA, 0, 0, 0, 0);
|
||||
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
|
||||
AudioAttributes.USAGE_ALARM);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false,
|
||||
AudioAttributes.USAGE_MEDIA);
|
||||
}
|
||||
|
||||
@@ -244,13 +246,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
|
||||
AudioAttributes.USAGE_ALARM);
|
||||
|
||||
// Media is a catch-all that includes games
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
|
||||
AudioAttributes.USAGE_MEDIA);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true,
|
||||
AudioAttributes.USAGE_GAME);
|
||||
}
|
||||
|
||||
@@ -262,17 +264,17 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
// Total silence will silence alarms, media and system noises (but not vibrations)
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_ALARM);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_MEDIA);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_GAME);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_VIBRATE);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_UNKNOWN);
|
||||
}
|
||||
|
||||
@@ -283,19 +285,19 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
// Alarms only mode will not silence alarms
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_ALARM);
|
||||
|
||||
// Alarms only mode will not silence media
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_MEDIA);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_GAME);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_UNKNOWN);
|
||||
|
||||
// Alarms only will silence system noises (but not vibrations)
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
|
||||
}
|
||||
|
||||
@@ -306,9 +308,9 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
// Alarms only mode will silence calls despite priority-mode config
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_NOTIFICATION_RINGTONE);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, true,
|
||||
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST);
|
||||
}
|
||||
|
||||
@@ -319,7 +321,7 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, false,
|
||||
AudioAttributes.USAGE_ALARM);
|
||||
}
|
||||
|
||||
@@ -334,18 +336,63 @@ public class ZenModeHelperTest extends UiServiceTestCase {
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
if (usage == AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) {
|
||||
// only mute audio, not vibrations
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, usage,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, true, usage,
|
||||
AppOpsManager.OP_PLAY_AUDIO);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false, usage,
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, false, usage,
|
||||
AppOpsManager.OP_VIBRATE);
|
||||
} else {
|
||||
boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
|
||||
!= AudioAttributes.SUPPRESSIBLE_NEVER;
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(shouldMute, usage);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true, shouldMute, usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyRestrictions_whitelist_priorityOnlyMode() {
|
||||
mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
|
||||
mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
verify(mAppOps).setRestriction(
|
||||
eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(new String[]{PKG_O}));
|
||||
verify(mAppOps).setRestriction(
|
||||
eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(new String[]{PKG_O}));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyRestrictions_whitelist_alarmsOnlyMode() {
|
||||
mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
|
||||
mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_ALARMS;
|
||||
mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
verify(mAppOps).setRestriction(
|
||||
eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(null));
|
||||
verify(mAppOps).setRestriction(
|
||||
eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(null));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyRestrictions_whitelist_totalSilenceMode() {
|
||||
mZenModeHelperSpy.setPriorityOnlyDndExemptPackages(new String[] {PKG_O});
|
||||
mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_NO_INTERRUPTIONS;
|
||||
mZenModeHelperSpy.mConsolidatedPolicy = new Policy(0, 0, 0, 0, 0);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
verify(mAppOps).setRestriction(
|
||||
eq(AppOpsManager.OP_PLAY_AUDIO), eq(usage), anyInt(), eq(null));
|
||||
verify(mAppOps).setRestriction(
|
||||
eq(AppOpsManager.OP_VIBRATE), eq(usage), anyInt(), eq(null));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZenUpgradeNotification() {
|
||||
// shows zen upgrade notification if stored settings says to shows,
|
||||
|
||||
Reference in New Issue
Block a user