NotificationManager.java revision d63f9321e62064660d426efd5abbd885c4a24652
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.annotation.SdkConstant;
22import android.app.Notification.Builder;
23import android.content.ComponentName;
24import android.content.Context;
25import android.content.pm.ParceledListSlice;
26import android.graphics.drawable.Icon;
27import android.net.Uri;
28import android.os.Bundle;
29import android.os.Handler;
30import android.os.IBinder;
31import android.os.Parcel;
32import android.os.Parcelable;
33import android.os.RemoteException;
34import android.os.ServiceManager;
35import android.os.StrictMode;
36import android.os.UserHandle;
37import android.provider.Settings.Global;
38import android.service.notification.IConditionListener;
39import android.service.notification.StatusBarNotification;
40import android.service.notification.ZenModeConfig;
41import android.util.ArraySet;
42import android.util.Log;
43
44import java.util.Objects;
45import java.util.List;
46
47/**
48 * Class to notify the user of events that happen.  This is how you tell
49 * the user that something has happened in the background. {@more}
50 *
51 * Notifications can take different forms:
52 * <ul>
53 *      <li>A persistent icon that goes in the status bar and is accessible
54 *          through the launcher, (when the user selects it, a designated Intent
55 *          can be launched),</li>
56 *      <li>Turning on or flashing LEDs on the device, or</li>
57 *      <li>Alerting the user by flashing the backlight, playing a sound,
58 *          or vibrating.</li>
59 * </ul>
60 *
61 * <p>
62 * Each of the notify methods takes an int id parameter and optionally a
63 * {@link String} tag parameter, which may be {@code null}.  These parameters
64 * are used to form a pair (tag, id), or ({@code null}, id) if tag is
65 * unspecified.  This pair identifies this notification from your app to the
66 * system, so that pair should be unique within your app.  If you call one
67 * of the notify methods with a (tag, id) pair that is currently active and
68 * a new set of notification parameters, it will be updated.  For example,
69 * if you pass a new status bar icon, the old icon in the status bar will
70 * be replaced with the new one.  This is also the same tag and id you pass
71 * to the {@link #cancel(int)} or {@link #cancel(String, int)} method to clear
72 * this notification.
73 *
74 * <p>
75 * You do not instantiate this class directly; instead, retrieve it through
76 * {@link android.content.Context#getSystemService}.
77 *
78 * <div class="special reference">
79 * <h3>Developer Guides</h3>
80 * <p>For a guide to creating notifications, read the
81 * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
82 * developer guide.</p>
83 * </div>
84 *
85 * @see android.app.Notification
86 * @see android.content.Context#getSystemService
87 */
88public class NotificationManager
89{
90    private static String TAG = "NotificationManager";
91    private static boolean localLOGV = false;
92
93    /**
94     * Intent that is broadcast when the state of {@link #getEffectsSuppressor()} changes.
95     * This broadcast is only sent to registered receivers.
96     *
97     * @hide
98     */
99    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
100    public static final String ACTION_EFFECTS_SUPPRESSOR_CHANGED
101            = "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED";
102
103    /**
104     * Intent that is broadcast when the state of getNotificationPolicy() changes.
105     * This broadcast is only sent to registered receivers.
106     */
107    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
108    public static final String ACTION_NOTIFICATION_POLICY_CHANGED
109            = "android.app.action.NOTIFICATION_POLICY_CHANGED";
110
111    /**
112     * Intent that is broadcast when the state of getCurrentInterruptionFilter() changes.
113     * This broadcast is only sent to registered receivers.
114     */
115    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
116    public static final String ACTION_INTERRUPTION_FILTER_CHANGED
117            = "android.app.action.INTERRUPTION_FILTER_CHANGED";
118
119    /**
120     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
121     *     Normal interruption filter.
122     */
123    public static final int INTERRUPTION_FILTER_ALL = 1;
124
125    /**
126     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
127     *     Priority interruption filter.
128     */
129    public static final int INTERRUPTION_FILTER_PRIORITY = 2;
130
131    /**
132     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
133     *     No interruptions filter.
134     */
135    public static final int INTERRUPTION_FILTER_NONE = 3;
136
137    /**
138     * {@link #getCurrentInterruptionFilter() Interruption filter} constant -
139     *     Alarms only interruption filter.
140     */
141    public static final int INTERRUPTION_FILTER_ALARMS = 4;
142
143    /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
144     * the value is unavailable for any reason.
145     */
146    public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
147
148    private static INotificationManager sService;
149
150    /** @hide */
151    static public INotificationManager getService()
152    {
153        if (sService != null) {
154            return sService;
155        }
156        IBinder b = ServiceManager.getService("notification");
157        sService = INotificationManager.Stub.asInterface(b);
158        return sService;
159    }
160
161    /*package*/ NotificationManager(Context context, Handler handler)
162    {
163        mContext = context;
164    }
165
166    /** {@hide} */
167    public static NotificationManager from(Context context) {
168        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
169    }
170
171    /**
172     * Post a notification to be shown in the status bar. If a notification with
173     * the same id has already been posted by your application and has not yet been canceled, it
174     * will be replaced by the updated information.
175     *
176     * @param id An identifier for this notification unique within your
177     *        application.
178     * @param notification A {@link Notification} object describing what to show the user. Must not
179     *        be null.
180     */
181    public void notify(int id, Notification notification)
182    {
183        notify(null, id, notification);
184    }
185
186    /**
187     * Post a notification to be shown in the status bar. If a notification with
188     * the same tag and id has already been posted by your application and has not yet been
189     * canceled, it will be replaced by the updated information.
190     *
191     * @param tag A string identifier for this notification.  May be {@code null}.
192     * @param id An identifier for this notification.  The pair (tag, id) must be unique
193     *        within your application.
194     * @param notification A {@link Notification} object describing what to
195     *        show the user. Must not be null.
196     */
197    public void notify(String tag, int id, Notification notification)
198    {
199        int[] idOut = new int[1];
200        INotificationManager service = getService();
201        String pkg = mContext.getPackageName();
202        if (notification.sound != null) {
203            notification.sound = notification.sound.getCanonicalUri();
204            if (StrictMode.vmFileUriExposureEnabled()) {
205                notification.sound.checkFileUriExposed("Notification.sound");
206            }
207        }
208        fixLegacySmallIcon(notification, pkg);
209        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
210        Notification stripped = notification.clone();
211        Builder.stripForDelivery(stripped);
212        try {
213            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
214                    stripped, idOut, UserHandle.myUserId());
215            if (id != idOut[0]) {
216                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
217            }
218        } catch (RemoteException e) {
219        }
220    }
221
222    /**
223     * @hide
224     */
225    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
226    {
227        int[] idOut = new int[1];
228        INotificationManager service = getService();
229        String pkg = mContext.getPackageName();
230        if (notification.sound != null) {
231            notification.sound = notification.sound.getCanonicalUri();
232            if (StrictMode.vmFileUriExposureEnabled()) {
233                notification.sound.checkFileUriExposed("Notification.sound");
234            }
235        }
236        fixLegacySmallIcon(notification, pkg);
237        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
238        Notification stripped = notification.clone();
239        Builder.stripForDelivery(stripped);
240        try {
241            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
242                    stripped, idOut, user.getIdentifier());
243            if (id != idOut[0]) {
244                Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
245            }
246        } catch (RemoteException e) {
247        }
248    }
249
250    private void fixLegacySmallIcon(Notification n, String pkg) {
251        if (n.getSmallIcon() == null && n.icon != 0) {
252            n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
253        }
254    }
255
256    /**
257     * Cancel a previously shown notification.  If it's transient, the view
258     * will be hidden.  If it's persistent, it will be removed from the status
259     * bar.
260     */
261    public void cancel(int id)
262    {
263        cancel(null, id);
264    }
265
266    /**
267     * Cancel a previously shown notification.  If it's transient, the view
268     * will be hidden.  If it's persistent, it will be removed from the status
269     * bar.
270     */
271    public void cancel(String tag, int id)
272    {
273        INotificationManager service = getService();
274        String pkg = mContext.getPackageName();
275        if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
276        try {
277            service.cancelNotificationWithTag(pkg, tag, id, UserHandle.myUserId());
278        } catch (RemoteException e) {
279        }
280    }
281
282    /**
283     * @hide
284     */
285    public void cancelAsUser(String tag, int id, UserHandle user)
286    {
287        INotificationManager service = getService();
288        String pkg = mContext.getPackageName();
289        if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
290        try {
291            service.cancelNotificationWithTag(pkg, tag, id, user.getIdentifier());
292        } catch (RemoteException e) {
293        }
294    }
295
296    /**
297     * Cancel all previously shown notifications. See {@link #cancel} for the
298     * detailed behavior.
299     */
300    public void cancelAll()
301    {
302        INotificationManager service = getService();
303        String pkg = mContext.getPackageName();
304        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
305        try {
306            service.cancelAllNotifications(pkg, UserHandle.myUserId());
307        } catch (RemoteException e) {
308        }
309    }
310
311    /**
312     * @hide
313     */
314    public ComponentName getEffectsSuppressor() {
315        INotificationManager service = getService();
316        try {
317            return service.getEffectsSuppressor();
318        } catch (RemoteException e) {
319            return null;
320        }
321    }
322
323    /**
324     * @hide
325     */
326    public boolean matchesCallFilter(Bundle extras) {
327        INotificationManager service = getService();
328        try {
329            return service.matchesCallFilter(extras);
330        } catch (RemoteException e) {
331            return false;
332        }
333    }
334
335    /**
336     * @hide
337     */
338    public boolean isSystemConditionProviderEnabled(String path) {
339        INotificationManager service = getService();
340        try {
341            return service.isSystemConditionProviderEnabled(path);
342        } catch (RemoteException e) {
343            return false;
344        }
345    }
346
347    /**
348     * @hide
349     */
350    public void setZenMode(int mode, Uri conditionId, String reason) {
351        INotificationManager service = getService();
352        try {
353            service.setZenMode(mode, conditionId, reason);
354        } catch (RemoteException e) {
355        }
356    }
357
358    /**
359     * @hide
360     */
361    public boolean setZenModeConfig(ZenModeConfig config, String reason) {
362        INotificationManager service = getService();
363        try {
364            return service.setZenModeConfig(config, reason);
365        } catch (RemoteException e) {
366            return false;
367        }
368    }
369
370    /**
371     * @hide
372     */
373    public void requestZenModeConditions(IConditionListener listener, int relevance) {
374        INotificationManager service = getService();
375        try {
376            service.requestZenModeConditions(listener, relevance);
377        } catch (RemoteException e) {
378        }
379    }
380
381    /**
382     * @hide
383     */
384    public int getZenMode() {
385        INotificationManager service = getService();
386        try {
387            return service.getZenMode();
388        } catch (RemoteException e) {
389        }
390        return Global.ZEN_MODE_OFF;
391    }
392
393    /**
394     * @hide
395     */
396    public ZenModeConfig getZenModeConfig() {
397        INotificationManager service = getService();
398        try {
399            return service.getZenModeConfig();
400        } catch (RemoteException e) {
401        }
402        return null;
403    }
404
405    /**
406     * Requests the ability to read/modify notification policy for the calling package.
407     *
408     * @param callback required, used to receive the granted or the denied signal.
409     * @param handler The handler used when receiving the result.
410     *                If null, the current thread is used.
411     */
412    public void requestPolicyAccess(@NonNull final NotificationPolicyAccessRequestCallback callback,
413            @Nullable Handler handler) {
414        checkRequired("callback", callback);
415        final Handler h = handler != null ? handler : new Handler();
416        INotificationManager service = getService();
417        try {
418            service.requestNotificationPolicyAccess(mContext.getOpPackageName(),
419                    new INotificationManagerCallback.Stub() {
420                @Override
421                public void onPolicyRequestResult(final boolean granted) throws RemoteException {
422                    h.post(new Runnable() {
423                        @Override
424                        public void run() {
425                            if (granted) {
426                                callback.onAccessGranted();
427                            } else {
428                                callback.onAccessDenied();
429                            }
430                        }
431                    });
432                }
433            });
434        } catch (RemoteException e) {
435        }
436    }
437
438    /** Callback for receiving the result of a policy access request. */
439    public static abstract class NotificationPolicyAccessRequestCallback {
440        /**
441         * Received if the request was granted for this package.
442         */
443        public abstract void onAccessGranted();
444
445        /**
446         * Received if the request was denied for this package.
447         */
448        public abstract void onAccessDenied();
449    }
450
451    /**
452     * Checks the ability to read/modify notification policy for the calling package.
453     *
454     * Returns true if the calling package can read/modify notification policy.
455     */
456    public boolean isNotificationPolicyAccessGranted() {
457        INotificationManager service = getService();
458        try {
459            return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
460        } catch (RemoteException e) {
461        }
462        return false;
463    }
464
465    /** @hide */
466    public boolean isNotificationPolicyAccessGrantedForPackage(String pkg) {
467        INotificationManager service = getService();
468        try {
469            return service.isNotificationPolicyAccessGrantedForPackage(pkg);
470        } catch (RemoteException e) {
471        }
472        return false;
473    }
474
475    /**
476     * Gets the current notification policy.
477     *
478     * <p>
479     * Only available if policy access is granted.
480     */
481    public Policy getNotificationPolicy() {
482        INotificationManager service = getService();
483        try {
484            return service.getNotificationPolicy(mContext.getOpPackageName());
485        } catch (RemoteException e) {
486        }
487        return null;
488    }
489
490    /**
491     * Sets the current notification policy.
492     *
493     * <p>
494     * Only available if policy access is granted.
495     *
496     * @param policy The new desired policy.
497     */
498    public void setNotificationPolicy(@NonNull Policy policy) {
499        checkRequired("policy", policy);
500        INotificationManager service = getService();
501        try {
502            service.setNotificationPolicy(mContext.getOpPackageName(), policy);
503        } catch (RemoteException e) {
504        }
505    }
506
507    /** @hide */
508    public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
509        INotificationManager service = getService();
510        try {
511            service.setNotificationPolicyAccessGranted(pkg, granted);
512        } catch (RemoteException e) {
513        }
514    }
515
516    /** @hide */
517    public ArraySet<String> getPackagesRequestingNotificationPolicyAccess() {
518        INotificationManager service = getService();
519        try {
520            final String[] pkgs = service.getPackagesRequestingNotificationPolicyAccess();
521            if (pkgs != null && pkgs.length > 0) {
522                final ArraySet<String> rt = new ArraySet<>(pkgs.length);
523                for (int i = 0; i < pkgs.length; i++) {
524                    rt.add(pkgs[i]);
525                }
526                return rt;
527            }
528        } catch (RemoteException e) {
529        }
530        return new ArraySet<String>();
531    }
532
533    private Context mContext;
534
535    private static void checkRequired(String name, Object value) {
536        if (value == null) {
537            throw new IllegalArgumentException(name + " is required");
538        }
539    }
540
541    /**
542     * Notification policy configuration.  Represents user-preferences for notification
543     * filtering and prioritization.
544     */
545    public static class Policy implements android.os.Parcelable {
546        /** Reminder notifications are prioritized. */
547        public static final int PRIORITY_CATEGORY_REMINDERS = 1 << 0;
548        /** Event notifications are prioritized. */
549        public static final int PRIORITY_CATEGORY_EVENTS = 1 << 1;
550        /** Message notifications are prioritized. */
551        public static final int PRIORITY_CATEGORY_MESSAGES = 1 << 2;
552        /** Calls are prioritized. */
553        public static final int PRIORITY_CATEGORY_CALLS = 1 << 3;
554        /** Calls from repeat callers are prioritized. */
555        public static final int PRIORITY_CATEGORY_REPEAT_CALLERS = 1 << 4;
556
557        private static final int[] ALL_PRIORITY_CATEGORIES = {
558            PRIORITY_CATEGORY_REMINDERS,
559            PRIORITY_CATEGORY_EVENTS,
560            PRIORITY_CATEGORY_MESSAGES,
561            PRIORITY_CATEGORY_CALLS,
562            PRIORITY_CATEGORY_REPEAT_CALLERS,
563        };
564
565        /** Any sender is prioritized. */
566        public static final int PRIORITY_SENDERS_ANY = 0;
567        /** Saved contacts are prioritized. */
568        public static final int PRIORITY_SENDERS_CONTACTS = 1;
569        /** Only starred contacts are prioritized. */
570        public static final int PRIORITY_SENDERS_STARRED = 2;
571
572        /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
573        public final int priorityCategories;
574
575        /** Notification senders to prioritize for calls. One of:
576         * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
577        public final int priorityCallSenders;
578
579        /** Notification senders to prioritize for messages. One of:
580         * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
581        public final int priorityMessageSenders;
582
583        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
584            this.priorityCategories = priorityCategories;
585            this.priorityCallSenders = priorityCallSenders;
586            this.priorityMessageSenders = priorityMessageSenders;
587        }
588
589        /** @hide */
590        public Policy(Parcel source) {
591            this(source.readInt(), source.readInt(), source.readInt());
592        }
593
594        @Override
595        public void writeToParcel(Parcel dest, int flags) {
596            dest.writeInt(priorityCategories);
597            dest.writeInt(priorityCallSenders);
598            dest.writeInt(priorityMessageSenders);
599        }
600
601        @Override
602        public int describeContents() {
603            return 0;
604        }
605
606        @Override
607        public int hashCode() {
608            return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders);
609        }
610
611        @Override
612        public boolean equals(Object o) {
613            if (!(o instanceof Policy)) return false;
614            if (o == this) return true;
615            final Policy other = (Policy) o;
616            return other.priorityCategories == priorityCategories
617                    && other.priorityCallSenders == priorityCallSenders
618                    && other.priorityMessageSenders == priorityMessageSenders;
619        }
620
621        @Override
622        public String toString() {
623            return "NotificationManager.Policy["
624                    + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
625                    + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
626                    + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
627                    + "]";
628        }
629
630        public static String priorityCategoriesToString(int priorityCategories) {
631            if (priorityCategories == 0) return "";
632            final StringBuilder sb = new StringBuilder();
633            for (int i = 0; i < ALL_PRIORITY_CATEGORIES.length; i++) {
634                final int priorityCategory = ALL_PRIORITY_CATEGORIES[i];
635                if ((priorityCategories & priorityCategory) != 0) {
636                    if (sb.length() > 0) sb.append(',');
637                    sb.append(priorityCategoryToString(priorityCategory));
638                }
639                priorityCategories &= ~priorityCategory;
640            }
641            if (priorityCategories != 0) {
642                if (sb.length() > 0) sb.append(',');
643                sb.append("PRIORITY_CATEGORY_UNKNOWN_").append(priorityCategories);
644            }
645            return sb.toString();
646        }
647
648        private static String priorityCategoryToString(int priorityCategory) {
649            switch (priorityCategory) {
650                case PRIORITY_CATEGORY_REMINDERS: return "PRIORITY_CATEGORY_REMINDERS";
651                case PRIORITY_CATEGORY_EVENTS: return "PRIORITY_CATEGORY_EVENTS";
652                case PRIORITY_CATEGORY_MESSAGES: return "PRIORITY_CATEGORY_MESSAGES";
653                case PRIORITY_CATEGORY_CALLS: return "PRIORITY_CATEGORY_CALLS";
654                case PRIORITY_CATEGORY_REPEAT_CALLERS: return "PRIORITY_CATEGORY_REPEAT_CALLERS";
655                default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
656            }
657        }
658
659        public static String prioritySendersToString(int prioritySenders) {
660            switch (prioritySenders) {
661                case PRIORITY_SENDERS_ANY: return "PRIORITY_SENDERS_ANY";
662                case PRIORITY_SENDERS_CONTACTS: return "PRIORITY_SENDERS_CONTACTS";
663                case PRIORITY_SENDERS_STARRED: return "PRIORITY_SENDERS_STARRED";
664                default: return "PRIORITY_SENDERS_UNKNOWN_" + prioritySenders;
665            }
666        }
667
668        public static final Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
669            @Override
670            public Policy createFromParcel(Parcel in) {
671                return new Policy(in);
672            }
673
674            @Override
675            public Policy[] newArray(int size) {
676                return new Policy[size];
677            }
678        };
679
680    }
681
682    /**
683     * Recover a list of active notifications: ones that have been posted by the calling app that
684     * have not yet been dismissed by the user or {@link #cancel(String, int)}ed by the app.
685     *
686     * Each notification is embedded in a {@link StatusBarNotification} object, including the
687     * original <code>tag</code> and <code>id</code> supplied to
688     * {@link #notify(String, int, Notification) notify()}
689     * (via {@link StatusBarNotification#getTag() getTag()} and
690     * {@link StatusBarNotification#getId() getId()}) as well as a copy of the original
691     * {@link Notification} object (via {@link StatusBarNotification#getNotification()}).
692     *
693     * @return An array of {@link StatusBarNotification}.
694     */
695    public StatusBarNotification[] getActiveNotifications() {
696        final INotificationManager service = getService();
697        final String pkg = mContext.getPackageName();
698        try {
699            final ParceledListSlice<StatusBarNotification> parceledList
700                    = service.getAppActiveNotifications(pkg, UserHandle.myUserId());
701            final List<StatusBarNotification> list = parceledList.getList();
702            return list.toArray(new StatusBarNotification[list.size()]);
703        } catch (RemoteException e) {
704            Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
705        }
706        return new StatusBarNotification[0];
707    }
708
709    /**
710     * Gets the current notification interruption filter.
711     *
712     * <p>
713     * The interruption filter defines which notifications are allowed to interrupt the user
714     * (e.g. via sound &amp; vibration) and is applied globally.
715     * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
716     * unavailable.
717     *
718     * <p>
719     * Only available if policy access is granted.
720     */
721    public final int getCurrentInterruptionFilter() {
722        final INotificationManager service = getService();
723        try {
724            return zenModeToInterruptionFilter(service.getZenMode());
725        } catch (RemoteException e) {
726            Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
727        }
728        return INTERRUPTION_FILTER_UNKNOWN;
729    }
730
731    /**
732     * Sets the current notification interruption filter.
733     *
734     * <p>
735     * The interruption filter defines which notifications are allowed to interrupt the user
736     * (e.g. via sound &amp; vibration) and is applied globally.
737     * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
738     * unavailable.
739     *
740     * <p>
741     * Only available if policy access is granted.
742     */
743    public final void setInterruptionFilter(int interruptionFilter) {
744        final INotificationManager service = getService();
745        try {
746            service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter);
747        } catch (RemoteException e) {
748            Log.e(TAG, "Unable to talk to notification manager. Woe!", e);
749        }
750    }
751
752    /** @hide */
753    public static int zenModeToInterruptionFilter(int zen) {
754        switch (zen) {
755            case Global.ZEN_MODE_OFF: return INTERRUPTION_FILTER_ALL;
756            case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return INTERRUPTION_FILTER_PRIORITY;
757            case Global.ZEN_MODE_ALARMS: return INTERRUPTION_FILTER_ALARMS;
758            case Global.ZEN_MODE_NO_INTERRUPTIONS: return INTERRUPTION_FILTER_NONE;
759            default: return INTERRUPTION_FILTER_UNKNOWN;
760        }
761    }
762
763    /** @hide */
764    public static int zenModeFromInterruptionFilter(int interruptionFilter, int defValue) {
765        switch (interruptionFilter) {
766            case INTERRUPTION_FILTER_ALL: return Global.ZEN_MODE_OFF;
767            case INTERRUPTION_FILTER_PRIORITY: return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
768            case INTERRUPTION_FILTER_ALARMS: return Global.ZEN_MODE_ALARMS;
769            case INTERRUPTION_FILTER_NONE:  return Global.ZEN_MODE_NO_INTERRUPTIONS;
770            default: return defValue;
771        }
772    }
773}
774