blob: 536aeb4d01639a52e1847bf8fcd4692287d25be6 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection;
import static android.app.Notification.CATEGORY_ALARM;
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.CATEGORY_EVENT;
import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.Notification.CATEGORY_REMINDER;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.app.Person;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationEntryBuilder;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SbnBuilder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class NotificationEntryTest extends SysuiTestCase {
private static final String TEST_PACKAGE_NAME = "test";
private static final int TEST_UID = 0;
private static final int UID_NORMAL = 123;
private static final NotificationChannel NOTIFICATION_CHANNEL =
new NotificationChannel("id", "name", NotificationChannel.USER_LOCKED_IMPORTANCE);
private int mId;
private NotificationEntry mEntry;
@Before
public void setup() {
Notification.Builder n = new Notification.Builder(mContext, "")
.setSmallIcon(R.drawable.ic_person)
.setContentTitle("Title")
.setContentText("Text");
mEntry = new NotificationEntryBuilder()
.setPkg(TEST_PACKAGE_NAME)
.setOpPkg(TEST_PACKAGE_NAME)
.setUid(TEST_UID)
.setId(mId++)
.setNotification(n.build())
.setUser(new UserHandle(ActivityManager.getCurrentUser()))
.build();
}
@Test
public void testIsExemptFromDndVisualSuppression_foreground() {
mEntry.getSbn().getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
assertTrue(mEntry.isExemptFromDndVisualSuppression());
assertFalse(mEntry.shouldSuppressAmbient());
}
@Test
public void testIsExemptFromDndVisualSuppression_media() {
Notification.Builder n = new Notification.Builder(mContext, "")
.setStyle(new Notification.MediaStyle()
.setMediaSession(mock(MediaSession.Token.class)))
.setSmallIcon(R.drawable.ic_person)
.setContentTitle("Title")
.setContentText("Text");
NotificationEntry e1 = new NotificationEntryBuilder()
.setNotification(n.build())
.build();
assertTrue(e1.isExemptFromDndVisualSuppression());
assertFalse(e1.shouldSuppressAmbient());
}
@Test
public void testIsExemptFromDndVisualSuppression_system() {
mEntry.mIsSystemNotification = true;
assertTrue(mEntry.isExemptFromDndVisualSuppression());
assertFalse(mEntry.shouldSuppressAmbient());
}
@Test
public void testIsNotExemptFromDndVisualSuppression_hiddenCategories() {
NotificationEntry entry = new NotificationEntryBuilder()
.setUid(UID_NORMAL)
.build();
entry.mIsSystemNotification = true;
modifyRanking(entry).setSuppressedVisualEffects(SUPPRESSED_EFFECT_AMBIENT).build();
modifySbn(entry)
.setNotification(
new Notification.Builder(mContext, "").setCategory(CATEGORY_CALL).build())
.build();
assertFalse(entry.isExemptFromDndVisualSuppression());
assertTrue(entry.shouldSuppressAmbient());
modifySbn(entry)
.setNotification(
new Notification.Builder(mContext, "")
.setCategory(CATEGORY_REMINDER)
.build())
.build();
assertFalse(entry.isExemptFromDndVisualSuppression());
modifySbn(entry)
.setNotification(
new Notification.Builder(mContext, "").setCategory(CATEGORY_ALARM).build())
.build();
assertFalse(entry.isExemptFromDndVisualSuppression());
modifySbn(entry)
.setNotification(
new Notification.Builder(mContext, "").setCategory(CATEGORY_EVENT).build())
.build();
assertFalse(entry.isExemptFromDndVisualSuppression());
modifySbn(entry)
.setNotification(
new Notification.Builder(mContext, "")
.setCategory(CATEGORY_MESSAGE)
.build())
.build();
assertFalse(entry.isExemptFromDndVisualSuppression());
}
@Test
public void testCreateNotificationDataEntry_RankingUpdate() {
StatusBarNotification sbn = new SbnBuilder().build();
sbn.getNotification().actions =
new Notification.Action[]{createContextualAction("appGeneratedAction")};
ArrayList<Notification.Action> systemGeneratedSmartActions =
createActions("systemGeneratedAction");
SnoozeCriterion snoozeCriterion = new SnoozeCriterion("id", "explanation", "confirmation");
ArrayList<SnoozeCriterion> snoozeCriterions = new ArrayList<>();
snoozeCriterions.add(snoozeCriterion);
Ranking ranking = new RankingBuilder()
.setKey(sbn.getKey())
.setSmartActions(systemGeneratedSmartActions)
.setChannel(NOTIFICATION_CHANNEL)
.setUserSentiment(Ranking.USER_SENTIMENT_NEGATIVE)
.setSnoozeCriteria(snoozeCriterions)
.build();
NotificationEntry entry =
new NotificationEntry(sbn, ranking);
assertEquals(systemGeneratedSmartActions, entry.getSmartActions());
assertEquals(NOTIFICATION_CHANNEL, entry.getChannel());
assertEquals(Ranking.USER_SENTIMENT_NEGATIVE, entry.getUserSentiment());
assertEquals(snoozeCriterions, entry.getSnoozeCriteria());
}
@Test
public void notificationDataEntry_testIsLastMessageFromReply() {
Person.Builder person = new Person.Builder()
.setName("name")
.setKey("abc")
.setUri("uri")
.setBot(true);
// EXTRA_MESSAGING_PERSON is the same Person as the sender in last message in EXTRA_MESSAGES
Bundle bundle = new Bundle();
bundle.putParcelable(Notification.EXTRA_MESSAGING_PERSON, person.build());
Bundle[] messagesBundle = new Bundle[]{new Notification.MessagingStyle.Message(
"text", 0, person.build()).toBundle()};
bundle.putParcelableArray(Notification.EXTRA_MESSAGES, messagesBundle);
Notification notification = new Notification.Builder(mContext, "test")
.addExtras(bundle)
.build();
NotificationEntry entry = new NotificationEntryBuilder()
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(notification)
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build();
entry.setHasSentReply();
assertTrue(entry.isLastMessageFromReply());
}
private Notification.Action createContextualAction(String title) {
return new Notification.Action.Builder(
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
title,
PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0))
.setContextual(true)
.build();
}
private Notification.Action createAction(String title) {
return new Notification.Action.Builder(
Icon.createWithResource(getContext(), android.R.drawable.sym_def_app_icon),
title,
PendingIntent.getBroadcast(getContext(), 0, new Intent("Action"), 0)).build();
}
private ArrayList<Notification.Action> createActions(String... titles) {
ArrayList<Notification.Action> actions = new ArrayList<>();
for (String title : titles) {
actions.add(createAction(title));
}
return actions;
}
}