Merge "Add granular control over disabled effects." into nyc-dev
am: 196a057 * commit '196a05724d73832571c6e4ad5372b05840ec041f': Add granular control over disabled effects. Change-Id: I453928754c89113f321df08a4ca8612660b1012c
This commit is contained in:
@@ -34725,7 +34725,9 @@ package android.service.notification {
|
||||
method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException;
|
||||
method public final void requestUnbind() throws android.os.RemoteException;
|
||||
method public final void setNotificationsShown(java.lang.String[]);
|
||||
field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
|
||||
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
|
||||
field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
|
||||
field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
|
||||
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
|
||||
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
|
||||
|
||||
@@ -37211,7 +37211,9 @@ package android.service.notification {
|
||||
method public final void setNotificationsShown(java.lang.String[]);
|
||||
method public final void setOnNotificationPostedTrim(int);
|
||||
method public void unregisterAsSystemService() throws android.os.RemoteException;
|
||||
field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
|
||||
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
|
||||
field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
|
||||
field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
|
||||
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
|
||||
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
|
||||
|
||||
@@ -34798,7 +34798,9 @@ package android.service.notification {
|
||||
method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException;
|
||||
method public final void requestUnbind() throws android.os.RemoteException;
|
||||
method public final void setNotificationsShown(java.lang.String[]);
|
||||
field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
|
||||
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
|
||||
field public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 2; // 0x2
|
||||
field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
|
||||
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
|
||||
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
|
||||
|
||||
@@ -123,6 +123,16 @@ public abstract class NotificationListenerService extends Service {
|
||||
* This does not change the interruption filter, only the effects. **/
|
||||
public static final int HINT_HOST_DISABLE_EFFECTS = 1;
|
||||
|
||||
/** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
|
||||
* should disable notification sound, but not phone calls.
|
||||
* This does not change the interruption filter, only the effects. **/
|
||||
public static final int HINT_HOST_DISABLE_NOTIFICATION_EFFECTS = 1 << 1;
|
||||
|
||||
/** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
|
||||
* should disable phone call sounds, buyt not notification sound.
|
||||
* This does not change the interruption filter, only the effects. **/
|
||||
public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 1 << 2;
|
||||
|
||||
/**
|
||||
* Whether notification suppressed by DND should not interruption visually when the screen is
|
||||
* off.
|
||||
|
||||
@@ -33,6 +33,8 @@ import static android.service.notification.NotificationRankerService.REASON_PROF
|
||||
import static android.service.notification.NotificationRankerService.REASON_UNAUTOBUNDLED;
|
||||
import static android.service.notification.NotificationRankerService.REASON_USER_STOPPED;
|
||||
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
|
||||
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_NOTIFICATION_EFFECTS;
|
||||
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_CALL_EFFECTS;
|
||||
import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF;
|
||||
import static android.service.notification.NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_ON;
|
||||
import static android.service.notification.NotificationListenerService.TRIM_FULL;
|
||||
@@ -114,6 +116,7 @@ import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.Xml;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
@@ -246,8 +249,9 @@ public class NotificationManagerService extends SystemService {
|
||||
private String mSoundNotificationKey;
|
||||
private String mVibrateNotificationKey;
|
||||
|
||||
private final ArraySet<ManagedServiceInfo> mListenersDisablingEffects = new ArraySet<>();
|
||||
private ComponentName mEffectsSuppressor;
|
||||
private final SparseArray<ArraySet<ManagedServiceInfo>> mListenersDisablingEffects =
|
||||
new SparseArray<ArraySet<ManagedServiceInfo>>();
|
||||
private List<ComponentName> mEffectsSuppressors = new ArrayList<ComponentName>();
|
||||
private int mListenerHints; // right now, all hints are global
|
||||
private int mInterruptionFilter = NotificationListenerService.INTERRUPTION_FILTER_UNKNOWN;
|
||||
|
||||
@@ -1112,23 +1116,112 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private void updateListenerHintsLocked() {
|
||||
final int hints = mListenersDisablingEffects.isEmpty() ? 0 : HINT_HOST_DISABLE_EFFECTS;
|
||||
final int hints = calculateHints();
|
||||
if (hints == mListenerHints) return;
|
||||
ZenLog.traceListenerHintsChanged(mListenerHints, hints, mListenersDisablingEffects.size());
|
||||
ZenLog.traceListenerHintsChanged(mListenerHints, hints, mEffectsSuppressors.size());
|
||||
mListenerHints = hints;
|
||||
scheduleListenerHintsChanged(hints);
|
||||
}
|
||||
|
||||
private void updateEffectsSuppressorLocked() {
|
||||
final ComponentName suppressor = !mListenersDisablingEffects.isEmpty()
|
||||
? mListenersDisablingEffects.valueAt(0).component : null;
|
||||
if (Objects.equals(suppressor, mEffectsSuppressor)) return;
|
||||
ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressor, suppressor);
|
||||
mEffectsSuppressor = suppressor;
|
||||
mZenModeHelper.setEffectsSuppressed(suppressor != null);
|
||||
final long updatedSuppressedEffects = calculateSuppressedEffects();
|
||||
if (updatedSuppressedEffects == mZenModeHelper.getSuppressedEffects()) return;
|
||||
final List<ComponentName> suppressors = getSuppressors();
|
||||
ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressors, suppressors, updatedSuppressedEffects);
|
||||
mEffectsSuppressors = suppressors;
|
||||
mZenModeHelper.setSuppressedEffects(updatedSuppressedEffects);
|
||||
sendRegisteredOnlyBroadcast(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
|
||||
}
|
||||
|
||||
private ArrayList<ComponentName> getSuppressors() {
|
||||
ArrayList<ComponentName> names = new ArrayList<ComponentName>();
|
||||
for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
|
||||
ArraySet<ManagedServiceInfo> serviceInfoList = mListenersDisablingEffects.valueAt(i);
|
||||
|
||||
for (ManagedServiceInfo info : serviceInfoList) {
|
||||
names.add(info.component);
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
private boolean removeDisabledHints(ManagedServiceInfo info) {
|
||||
return removeDisabledHints(info, 0);
|
||||
}
|
||||
|
||||
private boolean removeDisabledHints(ManagedServiceInfo info, int hints) {
|
||||
boolean removed = false;
|
||||
|
||||
for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
|
||||
final int hint = mListenersDisablingEffects.keyAt(i);
|
||||
final ArraySet<ManagedServiceInfo> listeners =
|
||||
mListenersDisablingEffects.valueAt(i);
|
||||
|
||||
if (hints == 0 || (hint & hints) == hint) {
|
||||
removed = removed || listeners.remove(info);
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
private void addDisabledHints(ManagedServiceInfo info, int hints) {
|
||||
if ((hints & HINT_HOST_DISABLE_EFFECTS) != 0) {
|
||||
addDisabledHint(info, HINT_HOST_DISABLE_EFFECTS);
|
||||
}
|
||||
|
||||
if ((hints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) {
|
||||
addDisabledHint(info, HINT_HOST_DISABLE_NOTIFICATION_EFFECTS);
|
||||
}
|
||||
|
||||
if ((hints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) {
|
||||
addDisabledHint(info, HINT_HOST_DISABLE_CALL_EFFECTS);
|
||||
}
|
||||
}
|
||||
|
||||
private void addDisabledHint(ManagedServiceInfo info, int hint) {
|
||||
if (mListenersDisablingEffects.indexOfKey(hint) < 0) {
|
||||
mListenersDisablingEffects.put(hint, new ArraySet<ManagedServiceInfo>());
|
||||
}
|
||||
|
||||
ArraySet<ManagedServiceInfo> hintListeners = mListenersDisablingEffects.get(hint);
|
||||
hintListeners.add(info);
|
||||
}
|
||||
|
||||
private int calculateHints() {
|
||||
int hints = 0;
|
||||
for (int i = mListenersDisablingEffects.size() - 1; i >= 0; --i) {
|
||||
int hint = mListenersDisablingEffects.keyAt(i);
|
||||
ArraySet<ManagedServiceInfo> serviceInfoList = mListenersDisablingEffects.valueAt(i);
|
||||
|
||||
if (!serviceInfoList.isEmpty()) {
|
||||
hints |= hint;
|
||||
}
|
||||
}
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
||||
private long calculateSuppressedEffects() {
|
||||
int hints = calculateHints();
|
||||
long suppressedEffects = 0;
|
||||
|
||||
if ((hints & HINT_HOST_DISABLE_EFFECTS) != 0) {
|
||||
suppressedEffects |= ZenModeHelper.SUPPRESSED_EFFECT_ALL;
|
||||
}
|
||||
|
||||
if ((hints & HINT_HOST_DISABLE_NOTIFICATION_EFFECTS) != 0) {
|
||||
suppressedEffects |= ZenModeHelper.SUPPRESSED_EFFECT_NOTIFICATIONS;
|
||||
}
|
||||
|
||||
if ((hints & HINT_HOST_DISABLE_CALL_EFFECTS) != 0) {
|
||||
suppressedEffects |= ZenModeHelper.SUPPRESSED_EFFECT_CALLS;
|
||||
}
|
||||
|
||||
return suppressedEffects;
|
||||
}
|
||||
|
||||
private void updateInterruptionFilterLocked() {
|
||||
int interruptionFilter = mZenModeHelper.getZenModeListenerInterruptionFilter();
|
||||
if (interruptionFilter == mInterruptionFilter) return;
|
||||
@@ -1651,11 +1744,14 @@ public class NotificationManagerService extends SystemService {
|
||||
try {
|
||||
synchronized (mNotificationList) {
|
||||
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
|
||||
final boolean disableEffects = (hints & HINT_HOST_DISABLE_EFFECTS) != 0;
|
||||
final int disableEffectsMask = HINT_HOST_DISABLE_EFFECTS
|
||||
| HINT_HOST_DISABLE_NOTIFICATION_EFFECTS
|
||||
| HINT_HOST_DISABLE_CALL_EFFECTS;
|
||||
final boolean disableEffects = (hints & disableEffectsMask) != 0;
|
||||
if (disableEffects) {
|
||||
mListenersDisablingEffects.add(info);
|
||||
addDisabledHints(info, hints);
|
||||
} else {
|
||||
mListenersDisablingEffects.remove(info);
|
||||
removeDisabledHints(info, hints);
|
||||
}
|
||||
updateListenerHintsLocked();
|
||||
updateEffectsSuppressorLocked();
|
||||
@@ -1913,7 +2009,7 @@ public class NotificationManagerService extends SystemService {
|
||||
@Override
|
||||
public ComponentName getEffectsSuppressor() {
|
||||
enforceSystemOrSystemUIOrVolume("INotificationManager.getEffectsSuppressor");
|
||||
return mEffectsSuppressor;
|
||||
return mEffectsSuppressors.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2273,9 +2369,19 @@ public class NotificationManagerService extends SystemService {
|
||||
pw.print(" mListenersDisablingEffects: (");
|
||||
N = mListenersDisablingEffects.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final ManagedServiceInfo listener = mListenersDisablingEffects.valueAt(i);
|
||||
if (i > 0) pw.print(',');
|
||||
pw.print(listener.component);
|
||||
final int hint = mListenersDisablingEffects.keyAt(i);
|
||||
if (i > 0) pw.print(';');
|
||||
pw.print("hint[" + hint + "]:");
|
||||
|
||||
final ArraySet<ManagedServiceInfo> listeners =
|
||||
mListenersDisablingEffects.valueAt(i);
|
||||
final int listenerSize = listeners.size();
|
||||
|
||||
for (int j = 0; j < listenerSize; j++) {
|
||||
if (i > 0) pw.print(',');
|
||||
final ManagedServiceInfo listener = listeners.valueAt(i);
|
||||
pw.print(listener.component);
|
||||
}
|
||||
}
|
||||
pw.println(')');
|
||||
pw.println("\n mRankerServicePackageName: " + mRankerServicePackageName);
|
||||
@@ -3808,7 +3914,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
|
||||
if (mListenersDisablingEffects.remove(removed)) {
|
||||
if (removeDisabledHints(removed)) {
|
||||
updateListenerHintsLocked();
|
||||
updateEffectsSuppressorLocked();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.util.Slog;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class ZenLog {
|
||||
private static final String TAG = "ZenLog";
|
||||
@@ -126,10 +127,11 @@ public class ZenLog {
|
||||
append(TYPE_DISABLE_EFFECTS, record.getKey() + "," + reason);
|
||||
}
|
||||
|
||||
public static void traceEffectsSuppressorChanged(ComponentName oldSuppressor,
|
||||
ComponentName newSuppressor) {
|
||||
append(TYPE_SUPPRESSOR_CHANGED, componentToString(oldSuppressor) + "->"
|
||||
+ componentToString(newSuppressor));
|
||||
public static void traceEffectsSuppressorChanged(List<ComponentName> oldSuppressors,
|
||||
List<ComponentName> newSuppressors, long suppressedEffects) {
|
||||
append(TYPE_SUPPRESSOR_CHANGED, "suppressed effects:" + suppressedEffects + ","
|
||||
+ componentListToString(oldSuppressors) + "->"
|
||||
+ componentListToString(newSuppressors));
|
||||
}
|
||||
|
||||
public static void traceListenerHintsChanged(int oldHints, int newHints, int listenerCount) {
|
||||
@@ -193,6 +195,19 @@ public class ZenLog {
|
||||
return component != null ? component.toShortString() : null;
|
||||
}
|
||||
|
||||
private static String componentListToString(List<ComponentName> components) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < components.size(); ++i) {
|
||||
if (i > 0) {
|
||||
stringBuilder.append(", ");
|
||||
}
|
||||
stringBuilder.append(componentToString(components.get(i)));
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static void append(int type, String msg) {
|
||||
synchronized(MSGS) {
|
||||
TIMES[sNext] = System.currentTimeMillis();
|
||||
|
||||
@@ -102,7 +102,12 @@ public class ZenModeHelper {
|
||||
private ZenModeConfig mConfig;
|
||||
private AudioManagerInternal mAudioManager;
|
||||
private PackageManager mPm;
|
||||
private boolean mEffectsSuppressed;
|
||||
private long mSuppressedEffects;
|
||||
|
||||
public static final long SUPPRESSED_EFFECT_NOTIFICATIONS = 1;
|
||||
public static final long SUPPRESSED_EFFECT_CALLS = 1 << 1;
|
||||
public static final long SUPPRESSED_EFFECT_ALL = SUPPRESSED_EFFECT_CALLS
|
||||
| SUPPRESSED_EFFECT_NOTIFICATIONS;
|
||||
|
||||
public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
|
||||
mContext = context;
|
||||
@@ -228,12 +233,16 @@ public class ZenModeHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public void setEffectsSuppressed(boolean effectsSuppressed) {
|
||||
if (mEffectsSuppressed == effectsSuppressed) return;
|
||||
mEffectsSuppressed = effectsSuppressed;
|
||||
public void setSuppressedEffects(long suppressedEffects) {
|
||||
if (mSuppressedEffects == suppressedEffects) return;
|
||||
mSuppressedEffects = suppressedEffects;
|
||||
applyRestrictions();
|
||||
}
|
||||
|
||||
public long getSuppressedEffects() {
|
||||
return mSuppressedEffects;
|
||||
}
|
||||
|
||||
public int getZenMode() {
|
||||
return mZenMode;
|
||||
}
|
||||
@@ -484,7 +493,8 @@ public class ZenModeHelper {
|
||||
synchronized (mConfig) {
|
||||
dump(pw, prefix, "mConfig", mConfig);
|
||||
}
|
||||
pw.print(prefix); pw.print("mEffectsSuppressed="); pw.println(mEffectsSuppressed);
|
||||
|
||||
pw.print(prefix); pw.print("mSuppressedEffects="); pw.println(mSuppressedEffects);
|
||||
mFiltering.dump(pw, prefix);
|
||||
mConditions.dump(pw, prefix);
|
||||
}
|
||||
@@ -708,9 +718,11 @@ public class ZenModeHelper {
|
||||
final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
|
||||
|
||||
// notification restrictions
|
||||
final boolean muteNotifications = mEffectsSuppressed;
|
||||
final boolean muteNotifications =
|
||||
(mSuppressedEffects & SUPPRESSED_EFFECT_NOTIFICATIONS) != 0;
|
||||
// call restrictions
|
||||
final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers;
|
||||
final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers
|
||||
|| (mSuppressedEffects & SUPPRESSED_EFFECT_CALLS) != 0;
|
||||
// total silence restrictions
|
||||
final boolean muteEverything = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user