Merge "DND behavior system sounds cannot bypass DND"
This commit is contained in:
committed by
Android (Google) Code Review
commit
1dd3f35be8
@@ -244,6 +244,7 @@ public final class AudioAttributes implements Parcelable {
|
||||
SUPPRESSIBLE_USAGES.put(USAGE_GAME, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
|
||||
SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
|
||||
SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
|
||||
SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN, SUPPRESSIBLE_MEDIA_SYSTEM_OTHER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,17 +43,16 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -1966,9 +1965,28 @@ public class AudioManager {
|
||||
*/
|
||||
private boolean querySoundEffectsEnabled(int user) {
|
||||
return Settings.System.getIntForUser(getContext().getContentResolver(),
|
||||
Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
|
||||
Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0
|
||||
&& !areSystemSoundsZenModeBlocked(getContext());
|
||||
}
|
||||
|
||||
private boolean areSystemSoundsZenModeBlocked(Context context) {
|
||||
int zenMode = Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.ZEN_MODE, 0);
|
||||
|
||||
switch (zenMode) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
return true;
|
||||
case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
|
||||
final NotificationManager noMan = (NotificationManager) context
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
return (noMan.getNotificationPolicy().priorityCategories
|
||||
& NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0;
|
||||
case Settings.Global.ZEN_MODE_OFF:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Sound effects.
|
||||
|
||||
@@ -28,6 +28,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.StatusBarManager;
|
||||
import android.app.trust.TrustManager;
|
||||
@@ -1691,6 +1692,8 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
mUiOffloadThread.submit(() -> {
|
||||
// If the stream is muted, don't play the sound
|
||||
if (mAudioManager.isStreamMute(mUiSoundsStreamType)) return;
|
||||
// If DND blocks the sound, don't play the sound
|
||||
if (areSystemSoundsZenModeBlocked(mContext)) return;
|
||||
|
||||
int id = mLockSounds.play(soundId,
|
||||
mLockSoundVolume, mLockSoundVolume, 1/*priortiy*/, 0/*loop*/, 1.0f/*rate*/);
|
||||
@@ -1702,6 +1705,25 @@ public class KeyguardViewMediator extends SystemUI {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areSystemSoundsZenModeBlocked(Context context) {
|
||||
int zenMode = Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.ZEN_MODE, 0);
|
||||
|
||||
switch (zenMode) {
|
||||
case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
|
||||
case Settings.Global.ZEN_MODE_ALARMS:
|
||||
return true;
|
||||
case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
|
||||
final NotificationManager noMan = (NotificationManager) context
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
return (noMan.getNotificationPolicy().priorityCategories
|
||||
& NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER) == 0;
|
||||
case Settings.Global.ZEN_MODE_OFF:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void playTrustedSound() {
|
||||
playSound(mTrustedSoundId);
|
||||
}
|
||||
|
||||
@@ -835,7 +835,8 @@ public class ZenModeHelper {
|
||||
// alarm restrictions
|
||||
final boolean muteMediaAndSystemSounds = zen && !mConfig.allowMediaSystemOther;
|
||||
// total silence restrictions
|
||||
final boolean muteEverything = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
|
||||
final boolean muteEverything = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS
|
||||
|| areAllBehaviorSoundsMuted();
|
||||
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
final int suppressionBehavior = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage);
|
||||
@@ -855,9 +856,11 @@ public class ZenModeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
protected void applyRestrictions(boolean mute, int usage) {
|
||||
final String[] exceptionPackages = null; // none (for now)
|
||||
|
||||
mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, usage,
|
||||
mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
|
||||
exceptionPackages);
|
||||
@@ -866,6 +869,12 @@ public class ZenModeHelper {
|
||||
exceptionPackages);
|
||||
}
|
||||
|
||||
private boolean areAllBehaviorSoundsMuted() {
|
||||
return !mConfig.allowAlarms && !mConfig.allowMediaSystemOther && !mConfig.allowReminders
|
||||
&& !mConfig.allowCalls && !mConfig.allowMessages && !mConfig.allowEvents
|
||||
&& !mConfig.allowRepeatCallers;
|
||||
}
|
||||
|
||||
private void applyZenToRingerMode() {
|
||||
if (mAudioManager == null) return;
|
||||
// force the ringer mode into compliance
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.android.server.notification;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -100,5 +100,34 @@ public class ZenModeHelperTest extends NotificationTestCase {
|
||||
AudioAttributes.USAGE_GAME);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
AudioAttributes.USAGE_ASSISTANCE_SONIFICATION);
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
|
||||
AudioAttributes.USAGE_UNKNOWN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZenAllCannotBypass() {
|
||||
// Only audio attributes with SUPPRESIBLE_NEVER can bypass
|
||||
mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
|
||||
mZenModeHelperSpy.mConfig.allowAlarms = false;
|
||||
mZenModeHelperSpy.mConfig.allowMediaSystemOther = false;
|
||||
mZenModeHelperSpy.mConfig.allowReminders = false;
|
||||
mZenModeHelperSpy.mConfig.allowCalls = false;
|
||||
mZenModeHelperSpy.mConfig.allowMessages = false;
|
||||
mZenModeHelperSpy.mConfig.allowEvents = false;
|
||||
mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowAlarms);
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowMediaSystemOther);
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowReminders);
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowCalls);
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowMessages);
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowEvents);
|
||||
assertFalse(mZenModeHelperSpy.mConfig.allowRepeatCallers);
|
||||
mZenModeHelperSpy.applyRestrictions();
|
||||
|
||||
for (int usage : AudioAttributes.SDK_USAGES) {
|
||||
boolean shouldMute = AudioAttributes.SUPPRESSIBLE_USAGES.get(usage)
|
||||
!= AudioAttributes.SUPPRESSIBLE_NEVER;
|
||||
verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(shouldMute, usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user