• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package com.android.settings.notification;
18 
19 import static android.app.slice.Slice.EXTRA_TOGGLE_STATE;
20 
21 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
22 
23 import android.annotation.ColorInt;
24 import android.app.NotificationManager;
25 import android.app.PendingIntent;
26 import android.content.ContentResolver;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.net.Uri;
31 import android.provider.Settings;
32 import android.provider.SettingsSlicesContract;
33 
34 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
35 import com.android.settings.R;
36 import com.android.settings.SubSettings;
37 import com.android.settings.Utils;
38 import com.android.settings.search.DatabaseIndexingUtils;
39 import com.android.settings.slices.SettingsSliceProvider;
40 import com.android.settings.slices.SliceBroadcastReceiver;
41 import com.android.settings.slices.SliceBuilderUtils;
42 
43 import androidx.slice.Slice;
44 import androidx.slice.builders.ListBuilder;
45 import androidx.slice.builders.SliceAction;
46 
47 import android.support.v4.graphics.drawable.IconCompat;
48 
49 public class ZenModeSliceBuilder {
50 
51     private static final String TAG = "ZenModeSliceBuilder";
52 
53     private static final String ZEN_MODE_KEY = "zen_mode";
54 
55     /**
56      * Backing Uri for the Zen Mode Slice.
57      */
58     public static final Uri ZEN_MODE_URI = new Uri.Builder()
59             .scheme(ContentResolver.SCHEME_CONTENT)
60             .authority(SettingsSliceProvider.SLICE_AUTHORITY)
61             .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
62             .appendPath(ZEN_MODE_KEY)
63             .build();
64 
65     /**
66      * Action notifying a change on the Zen Mode Slice.
67      */
68     public static final String ACTION_ZEN_MODE_SLICE_CHANGED =
69             "com.android.settings.notification.ZEN_MODE_CHANGED";
70 
71     public static final IntentFilter INTENT_FILTER = new IntentFilter();
72 
73     static {
74         INTENT_FILTER.addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
75         INTENT_FILTER.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
76         INTENT_FILTER.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL);
77     }
78 
ZenModeSliceBuilder()79     private ZenModeSliceBuilder() {
80     }
81 
82     /**
83      * Return a ZenMode Slice bound to {@link #ZEN_MODE_URI}.
84      * <p>
85      * Note that you should register a listener for {@link #INTENT_FILTER} to get changes for
86      * ZenMode.
87      */
getSlice(Context context)88     public static Slice getSlice(Context context) {
89         final boolean isZenModeEnabled = isZenModeEnabled(context);
90         final CharSequence title = context.getText(R.string.zen_mode_settings_title);
91         @ColorInt final int color = Utils.getColorAccent(context);
92         final PendingIntent toggleAction = getBroadcastIntent(context);
93         final PendingIntent primaryAction = getPrimaryAction(context);
94         final SliceAction primarySliceAction = new SliceAction(primaryAction,
95                 (IconCompat) null /* icon */, title);
96         final SliceAction toggleSliceAction = new SliceAction(toggleAction, null /* actionTitle */,
97                 isZenModeEnabled);
98 
99         return new ListBuilder(context, ZEN_MODE_URI, ListBuilder.INFINITY)
100                 .setAccentColor(color)
101                 .addRow(b -> b
102                         .setTitle(title)
103                         .addEndItem(toggleSliceAction)
104                         .setPrimaryAction(primarySliceAction))
105                 .build();
106     }
107 
108     /**
109      * Update the current ZenMode status to the boolean value keyed by
110      * {@link android.app.slice.Slice#EXTRA_TOGGLE_STATE} on {@param intent}.
111      */
handleUriChange(Context context, Intent intent)112     public static void handleUriChange(Context context, Intent intent) {
113         final boolean zenModeOn = intent.getBooleanExtra(EXTRA_TOGGLE_STATE, false);
114         final int zenMode;
115         if (zenModeOn) {
116             zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
117         } else {
118             zenMode = Settings.Global.ZEN_MODE_OFF;
119         }
120         NotificationManager.from(context).setZenMode(zenMode, null /* conditionId */, TAG);
121         // Do not notifyChange on Uri. The service takes longer to update the current value than it
122         // does for the Slice to check the current value again. Let {@link SliceBroadcastRelay}
123         // handle it.
124     }
125 
getIntent(Context context)126     public static Intent getIntent(Context context) {
127         final Uri contentUri = new Uri.Builder().appendPath(ZEN_MODE_KEY).build();
128         final String screenTitle = context.getText(R.string.zen_mode_settings_title).toString();
129         return DatabaseIndexingUtils.buildSearchResultPageIntent(context,
130                 ZenModeSettings.class.getName(), ZEN_MODE_KEY, screenTitle,
131                 MetricsEvent.NOTIFICATION_ZEN_MODE)
132                 .setClassName(context.getPackageName(), SubSettings.class.getName())
133                 .setData(contentUri);
134     }
135 
isZenModeEnabled(Context context)136     private static boolean isZenModeEnabled(Context context) {
137         final NotificationManager manager = context.getSystemService(NotificationManager.class);
138         final int zenMode = manager.getZenMode();
139 
140         switch (zenMode) {
141             case Settings.Global.ZEN_MODE_ALARMS:
142             case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
143             case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
144                 return true;
145             case Settings.Global.ZEN_MODE_OFF:
146             default:
147                 return false;
148         }
149     }
150 
getPrimaryAction(Context context)151     private static PendingIntent getPrimaryAction(Context context) {
152         final Intent intent = getIntent(context);
153         return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
154     }
155 
getBroadcastIntent(Context context)156     private static PendingIntent getBroadcastIntent(Context context) {
157         final Intent intent = new Intent(ACTION_ZEN_MODE_SLICE_CHANGED)
158                 .setClass(context, SliceBroadcastReceiver.class);
159         return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
160                 PendingIntent.FLAG_CANCEL_CURRENT);
161     }
162 }
163