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 distriZenbuted 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.server.notification;
18 
19 import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;
20 
21 import static junit.framework.TestCase.assertEquals;
22 import static junit.framework.TestCase.assertFalse;
23 import static junit.framework.TestCase.assertNotNull;
24 import static junit.framework.TestCase.assertNull;
25 import static junit.framework.TestCase.assertTrue;
26 
27 import android.app.NotificationManager.Policy;
28 import android.content.ComponentName;
29 import android.net.Uri;
30 import android.provider.Settings;
31 import android.service.notification.Condition;
32 import android.service.notification.ZenModeConfig;
33 import android.service.notification.ZenModeConfig.EventInfo;
34 import android.service.notification.ZenPolicy;
35 import android.util.Xml;
36 
37 import androidx.test.filters.SmallTest;
38 import androidx.test.runner.AndroidJUnit4;
39 
40 import com.android.modules.utils.TypedXmlPullParser;
41 import com.android.modules.utils.TypedXmlSerializer;
42 import com.android.server.UiServiceTestCase;
43 
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.xmlpull.v1.XmlPullParserException;
47 
48 import java.io.BufferedInputStream;
49 import java.io.BufferedOutputStream;
50 import java.io.ByteArrayInputStream;
51 import java.io.ByteArrayOutputStream;
52 import java.io.IOException;
53 
54 @SmallTest
55 @RunWith(AndroidJUnit4.class)
56 public class ZenModeConfigTest extends UiServiceTestCase {
57 
58     @Test
testPriorityOnlyMutingAllNotifications()59     public void testPriorityOnlyMutingAllNotifications() {
60         ZenModeConfig config = getMutedRingerConfig();
61         assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
62 
63         config.allowReminders = true;
64         assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
65         config.allowReminders = false;
66 
67         config.areChannelsBypassingDnd = true;
68         assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
69         config.areChannelsBypassingDnd = false;
70 
71         assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
72     }
73 
74     @Test
testZenPolicyNothingSetToNotificationPolicy()75     public void testZenPolicyNothingSetToNotificationPolicy() {
76         ZenModeConfig config = getCustomConfig();
77         ZenPolicy zenPolicy = new ZenPolicy.Builder().build();
78         assertEquals(config.toNotificationPolicy(), config.toNotificationPolicy(zenPolicy));
79     }
80 
81     @Test
testZenPolicyToNotificationPolicy()82     public void testZenPolicyToNotificationPolicy() {
83         ZenModeConfig config = getMutedAllConfig();
84         config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_BADGE;
85 
86         // Explicitly allow conversations from priority senders to make sure that goes through
87         ZenPolicy zenPolicy = new ZenPolicy.Builder()
88                 .allowAlarms(true)
89                 .allowReminders(true)
90                 .allowEvents(true)
91                 .allowConversations(CONVERSATION_SENDERS_IMPORTANT)
92                 .showLights(false)
93                 .showInAmbientDisplay(false)
94                 .build();
95 
96         Policy originalPolicy = config.toNotificationPolicy();
97         int priorityCategories = originalPolicy.priorityCategories;
98         int priorityCallSenders = originalPolicy.priorityCallSenders;
99         int priorityMessageSenders = originalPolicy.priorityMessageSenders;
100         int priorityConversationsSenders = CONVERSATION_SENDERS_IMPORTANT;
101         int suppressedVisualEffects = originalPolicy.suppressedVisualEffects;
102         priorityCategories |= Policy.PRIORITY_CATEGORY_ALARMS;
103         priorityCategories |= Policy.PRIORITY_CATEGORY_REMINDERS;
104         priorityCategories |= Policy.PRIORITY_CATEGORY_EVENTS;
105         priorityCategories |= Policy.PRIORITY_CATEGORY_CONVERSATIONS;
106         suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS;
107         suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
108 
109         Policy expectedPolicy = new Policy(priorityCategories, priorityCallSenders,
110                 priorityMessageSenders, suppressedVisualEffects, 0, priorityConversationsSenders);
111         assertEquals(expectedPolicy, config.toNotificationPolicy(zenPolicy));
112     }
113 
114     @Test
testZenConfigToZenPolicy()115     public void testZenConfigToZenPolicy() {
116         ZenPolicy expected = new ZenPolicy.Builder()
117                 .allowAlarms(true)
118                 .allowReminders(true)
119                 .allowEvents(true)
120                 .showLights(false)
121                 .showBadges(false)
122                 .showInAmbientDisplay(false)
123                 .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
124                 .allowMessages(ZenPolicy.PEOPLE_TYPE_STARRED)
125                 .allowConversations(ZenPolicy.CONVERSATION_SENDERS_NONE)
126                 .build();
127 
128         ZenModeConfig config = getMutedAllConfig();
129         config.allowAlarms = true;
130         config.allowReminders = true;
131         config.allowEvents = true;
132         config.allowCalls = true;
133         config.allowCallsFrom = Policy.PRIORITY_SENDERS_CONTACTS;
134         config.allowMessages = true;
135         config.allowMessagesFrom = Policy.PRIORITY_SENDERS_STARRED;
136         config.allowConversations = false;
137         config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_BADGE;
138         config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_LIGHTS;
139         config.suppressedVisualEffects |= Policy.SUPPRESSED_EFFECT_AMBIENT;
140         ZenPolicy actual = config.toZenPolicy();
141 
142         assertEquals(expected.getVisualEffectBadge(), actual.getVisualEffectBadge());
143         assertEquals(expected.getPriorityCategoryAlarms(), actual.getPriorityCategoryAlarms());
144         assertEquals(expected.getPriorityCategoryReminders(),
145                 actual.getPriorityCategoryReminders());
146         assertEquals(expected.getPriorityCategoryEvents(), actual.getPriorityCategoryEvents());
147         assertEquals(expected.getVisualEffectLights(), actual.getVisualEffectLights());
148         assertEquals(expected.getVisualEffectAmbient(), actual.getVisualEffectAmbient());
149         assertEquals(expected.getPriorityConversationSenders(),
150                 actual.getPriorityConversationSenders());
151         assertEquals(expected.getPriorityCallSenders(), actual.getPriorityCallSenders());
152         assertEquals(expected.getPriorityMessageSenders(), actual.getPriorityMessageSenders());
153     }
154 
155     @Test
testPriorityOnlyMutingAll()156     public void testPriorityOnlyMutingAll() {
157         ZenModeConfig config = getMutedAllConfig();
158         assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
159         assertTrue(ZenModeConfig.areAllZenBehaviorSoundsMuted(config));
160 
161         config.allowReminders = true;
162         assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
163         assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config));
164         config.allowReminders = false;
165 
166         config.areChannelsBypassingDnd = true;
167         assertFalse(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
168         assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config));
169         config.areChannelsBypassingDnd = false;
170 
171         config.allowAlarms = true;
172         assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
173         assertFalse(ZenModeConfig.areAllZenBehaviorSoundsMuted(config));
174         config.allowAlarms = false;
175 
176         assertTrue(ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(config));
177         assertTrue(ZenModeConfig.areAllZenBehaviorSoundsMuted(config));
178     }
179 
180     @Test
testParseOldEvent()181     public void testParseOldEvent() {
182         EventInfo oldEvent = new EventInfo();
183         oldEvent.userId = 1;
184         oldEvent.calName = "calName";
185         oldEvent.calendarId = null; // old events will have null ids
186 
187         Uri conditionId = ZenModeConfig.toEventConditionId(oldEvent);
188         EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId);
189         assertEquals(oldEvent, eventParsed);
190     }
191 
192     @Test
testParseNewEvent()193     public void testParseNewEvent() {
194         EventInfo event = new EventInfo();
195         event.userId = 1;
196         event.calName = "calName";
197         event.calendarId = 12345L;
198 
199         Uri conditionId = ZenModeConfig.toEventConditionId(event);
200         EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId);
201         assertEquals(event, eventParsed);
202     }
203 
204     @Test
testRuleXml()205     public void testRuleXml() throws Exception {
206         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
207         rule.configurationActivity = new ComponentName("a", "a");
208         rule.component = new ComponentName("b", "b");
209         rule.conditionId = new Uri.Builder().scheme("hello").build();
210         rule.condition = new Condition(rule.conditionId, "", Condition.STATE_TRUE);
211         rule.enabled = true;
212         rule.creationTime = 123;
213         rule.id = "id";
214         rule.zenMode = Settings.Global.ZEN_MODE_ALARMS;
215         rule.modified = true;
216         rule.name = "name";
217         rule.snoozing = true;
218         rule.pkg = "b";
219 
220         ByteArrayOutputStream baos = new ByteArrayOutputStream();
221         writeRuleXml(rule, baos);
222         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
223         ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
224 
225         assertEquals("b", fromXml.pkg);
226         // always resets on reboot
227         assertFalse(fromXml.snoozing);
228         //should all match original
229         assertEquals(rule.component, fromXml.component);
230         assertEquals(rule.configurationActivity, fromXml.configurationActivity);
231         assertNull(fromXml.enabler);
232         assertEquals(rule.condition, fromXml.condition);
233         assertEquals(rule.enabled, fromXml.enabled);
234         assertEquals(rule.creationTime, fromXml.creationTime);
235         assertEquals(rule.modified, fromXml.modified);
236         assertEquals(rule.conditionId, fromXml.conditionId);
237         assertEquals(rule.name, fromXml.name);
238         assertEquals(rule.zenMode, fromXml.zenMode);
239     }
240 
241     @Test
testRuleXml_pkg_component()242     public void testRuleXml_pkg_component() throws Exception {
243         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
244         rule.configurationActivity = new ComponentName("a", "a");
245         rule.component = new ComponentName("b", "b");
246 
247         ByteArrayOutputStream baos = new ByteArrayOutputStream();
248         writeRuleXml(rule, baos);
249         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
250         ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
251 
252         assertEquals("b", fromXml.pkg);
253     }
254 
255     @Test
testRuleXml_pkg_configActivity()256     public void testRuleXml_pkg_configActivity() throws Exception {
257         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
258         rule.configurationActivity = new ComponentName("a", "a");
259 
260         ByteArrayOutputStream baos = new ByteArrayOutputStream();
261         writeRuleXml(rule, baos);
262         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
263         ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
264 
265         assertNull(fromXml.pkg);
266     }
267 
268     @Test
testRuleXml_getPkg_nullPkg()269     public void testRuleXml_getPkg_nullPkg() throws Exception {
270         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
271         rule.enabled = true;
272         rule.configurationActivity = new ComponentName("a", "a");
273 
274         ByteArrayOutputStream baos = new ByteArrayOutputStream();
275         writeRuleXml(rule, baos);
276         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
277         ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
278         assertEquals("a", fromXml.getPkg());
279 
280         fromXml.condition = new Condition(Uri.EMPTY, "", Condition.STATE_TRUE);
281         assertTrue(fromXml.isAutomaticActive());
282     }
283 
284     @Test
testRuleXml_emptyConditionId()285     public void testRuleXml_emptyConditionId() throws Exception {
286         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
287         rule.conditionId = Uri.EMPTY;
288 
289         ByteArrayOutputStream baos = new ByteArrayOutputStream();
290         writeRuleXml(rule, baos);
291         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
292         ZenModeConfig.ZenRule fromXml = readRuleXml(bais);
293 
294         assertEquals(rule.condition, fromXml.condition);
295     }
296 
297     @Test
testZenPolicyXml_allUnset()298     public void testZenPolicyXml_allUnset() throws Exception {
299         ZenPolicy policy = new ZenPolicy.Builder().build();
300 
301         ByteArrayOutputStream baos = new ByteArrayOutputStream();
302         writePolicyXml(policy, baos);
303         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
304         ZenPolicy fromXml = readPolicyXml(bais);
305 
306         // nothing was set, so we should have nothing from the parser
307         assertNull(fromXml);
308     }
309 
310     @Test
testZenPolicyXml()311     public void testZenPolicyXml() throws Exception {
312         ZenPolicy policy = new ZenPolicy.Builder()
313                 .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS)
314                 .allowMessages(ZenPolicy.PEOPLE_TYPE_NONE)
315                 .allowConversations(ZenPolicy.CONVERSATION_SENDERS_IMPORTANT)
316                 .allowRepeatCallers(true)
317                 .allowAlarms(true)
318                 .allowMedia(false)
319                 .allowSystem(true)
320                 .allowReminders(false)
321                 .allowEvents(true)
322                 .hideAllVisualEffects()
323                 .showVisualEffect(ZenPolicy.VISUAL_EFFECT_AMBIENT, true)
324                 .build();
325 
326         ByteArrayOutputStream baos = new ByteArrayOutputStream();
327         writePolicyXml(policy, baos);
328         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
329         ZenPolicy fromXml = readPolicyXml(bais);
330 
331         assertNotNull(fromXml);
332         assertEquals(policy.getPriorityCategoryCalls(), fromXml.getPriorityCategoryCalls());
333         assertEquals(policy.getPriorityCallSenders(), fromXml.getPriorityCallSenders());
334         assertEquals(policy.getPriorityCategoryMessages(), fromXml.getPriorityCategoryMessages());
335         assertEquals(policy.getPriorityMessageSenders(), fromXml.getPriorityMessageSenders());
336         assertEquals(policy.getPriorityCategoryConversations(),
337                 fromXml.getPriorityCategoryConversations());
338         assertEquals(policy.getPriorityConversationSenders(),
339                 fromXml.getPriorityConversationSenders());
340         assertEquals(policy.getPriorityCategoryRepeatCallers(),
341                 fromXml.getPriorityCategoryRepeatCallers());
342         assertEquals(policy.getPriorityCategoryAlarms(), fromXml.getPriorityCategoryAlarms());
343         assertEquals(policy.getPriorityCategoryMedia(), fromXml.getPriorityCategoryMedia());
344         assertEquals(policy.getPriorityCategorySystem(), fromXml.getPriorityCategorySystem());
345         assertEquals(policy.getPriorityCategoryReminders(), fromXml.getPriorityCategoryReminders());
346         assertEquals(policy.getPriorityCategoryEvents(), fromXml.getPriorityCategoryEvents());
347 
348         assertEquals(policy.getVisualEffectFullScreenIntent(),
349                 fromXml.getVisualEffectFullScreenIntent());
350         assertEquals(policy.getVisualEffectLights(), fromXml.getVisualEffectLights());
351         assertEquals(policy.getVisualEffectPeek(), fromXml.getVisualEffectPeek());
352         assertEquals(policy.getVisualEffectStatusBar(), fromXml.getVisualEffectStatusBar());
353         assertEquals(policy.getVisualEffectBadge(), fromXml.getVisualEffectBadge());
354         assertEquals(policy.getVisualEffectAmbient(), fromXml.getVisualEffectAmbient());
355         assertEquals(policy.getVisualEffectNotificationList(),
356                 fromXml.getVisualEffectNotificationList());
357     }
358 
getMutedRingerConfig()359     private ZenModeConfig getMutedRingerConfig() {
360         ZenModeConfig config = new ZenModeConfig();
361         // Allow alarms, media
362         config.allowAlarms = true;
363         config.allowMedia = true;
364 
365         // All sounds that respect the ringer are not allowed
366         config.allowSystem = false;
367         config.allowCalls = false;
368         config.allowRepeatCallers = false;
369         config.allowMessages = false;
370         config.allowReminders = false;
371         config.allowEvents = false;
372         config.areChannelsBypassingDnd = false;
373 
374         config.suppressedVisualEffects = 0;
375 
376         return config;
377     }
378 
getCustomConfig()379     private ZenModeConfig getCustomConfig() {
380         ZenModeConfig config = new ZenModeConfig();
381         // Some sounds allowed
382         config.allowAlarms = true;
383         config.allowMedia = false;
384         config.allowSystem = false;
385         config.allowCalls = true;
386         config.allowRepeatCallers = true;
387         config.allowMessages = false;
388         config.allowReminders = false;
389         config.allowEvents = false;
390         config.areChannelsBypassingDnd = false;
391         config.allowCallsFrom = ZenModeConfig.SOURCE_ANYONE;
392         config.allowMessagesFrom = ZenModeConfig.SOURCE_ANYONE;
393         config.allowConversations = true;
394         config.allowConversationsFrom = CONVERSATION_SENDERS_IMPORTANT;
395 
396         config.suppressedVisualEffects = 0;
397         return config;
398     }
399 
getMutedAllConfig()400     private ZenModeConfig getMutedAllConfig() {
401         ZenModeConfig config = new ZenModeConfig();
402         // No sounds allowed
403         config.allowAlarms = false;
404         config.allowMedia = false;
405         config.allowSystem = false;
406         config.allowCalls = false;
407         config.allowRepeatCallers = false;
408         config.allowMessages = false;
409         config.allowReminders = false;
410         config.allowEvents = false;
411         config.areChannelsBypassingDnd = false;
412         config.allowConversations = false;
413         config.allowConversationsFrom = ZenPolicy.CONVERSATION_SENDERS_NONE;
414 
415         config.suppressedVisualEffects = 0;
416         return config;
417     }
418 
writeRuleXml(ZenModeConfig.ZenRule rule, ByteArrayOutputStream os)419     private void writeRuleXml(ZenModeConfig.ZenRule rule, ByteArrayOutputStream os)
420             throws IOException {
421         String tag = "tag";
422 
423         TypedXmlSerializer out = Xml.newFastSerializer();
424         out.setOutput(new BufferedOutputStream(os), "utf-8");
425         out.startDocument(null, true);
426         out.startTag(null, tag);
427         ZenModeConfig.writeRuleXml(rule, out);
428         out.endTag(null, tag);
429         out.endDocument();
430     }
431 
readRuleXml(ByteArrayInputStream is)432     private ZenModeConfig.ZenRule readRuleXml(ByteArrayInputStream is)
433             throws XmlPullParserException, IOException {
434         TypedXmlPullParser parser = Xml.newFastPullParser();
435         parser.setInput(new BufferedInputStream(is), null);
436         parser.nextTag();
437         return ZenModeConfig.readRuleXml(parser);
438     }
439 
writePolicyXml(ZenPolicy policy, ByteArrayOutputStream os)440     private void writePolicyXml(ZenPolicy policy, ByteArrayOutputStream os) throws IOException {
441         String tag = "tag";
442 
443         TypedXmlSerializer out = Xml.newFastSerializer();
444         out.setOutput(new BufferedOutputStream(os), "utf-8");
445         out.startDocument(null, true);
446         out.startTag(null, tag);
447         ZenModeConfig.writeZenPolicyXml(policy, out);
448         out.endTag(null, tag);
449         out.endDocument();
450     }
451 
readPolicyXml(ByteArrayInputStream is)452     private ZenPolicy readPolicyXml(ByteArrayInputStream is)
453             throws XmlPullParserException, IOException {
454         TypedXmlPullParser parser = Xml.newFastPullParser();
455         parser.setInput(new BufferedInputStream(is), null);
456         parser.nextTag();
457         return ZenModeConfig.readZenPolicyXml(parser);
458     }
459 }
460