/** * Copyright (C) 2018 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 android.ext.services.notification; import static android.app.Notification.FLAG_FOREGROUND_SERVICE; import static android.app.NotificationManager.IMPORTANCE_HIGH; import static android.media.AudioAttributes.USAGE_ALARM; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationChannel; import android.app.Person; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.testing.TestableContext; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; @RunWith(AndroidJUnit4.class) public class NotificationEntryTest { private String mPkg = "pkg"; private int mUid = 2018; @Mock private PackageManager mPackageManager; @Mock private ApplicationInfo mAppInfo; @Mock private SmsHelper mSmsHelper; private static final String DEFAULT_SMS_PACKAGE_NAME = "foo"; @Rule public final TestableContext mContext = new TestableContext(InstrumentationRegistry.getContext(), null); private StatusBarNotification generateSbn(String channelId) { Notification n = new Notification.Builder(mContext, channelId) .setContentTitle("foo") .build(); return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, 0, n, UserHandle.SYSTEM, 0); } private StatusBarNotification generateSbn(String channelId, String packageName) { Notification n = new Notification.Builder(mContext, channelId) .setContentTitle("foo") .build(); return new StatusBarNotification(packageName, packageName, 0, "tag", mUid, mUid, 0, n, UserHandle.SYSTEM, 0); } private StatusBarNotification generateSbn(Notification n) { return new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, mUid, 0, n, UserHandle.SYSTEM, 0); } @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mPkg = mContext.getPackageName(); mUid = Process.myUid(); when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) .thenReturn(mAppInfo); mAppInfo.targetSdkVersion = Build.VERSION_CODES.P; when(mSmsHelper.getDefaultSmsPackage()).thenReturn(DEFAULT_SMS_PACKAGE_NAME); } @Test public void testHasPerson() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); StatusBarNotification sbn = generateSbn(channel.getId()); ArrayList people = new ArrayList<>(); people.add(new Person.Builder().setKey("mailto:testing@android.com").build()); sbn.getNotification().extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, sbn, channel, mSmsHelper); assertTrue(entry.involvesPeople()); } @Test public void testNotPerson() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); StatusBarNotification sbn = generateSbn(channel.getId()); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, sbn, channel, mSmsHelper); assertFalse(entry.involvesPeople()); } @Test public void testHasPerson_matchesDefaultSmsApp() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); StatusBarNotification sbn = generateSbn(channel.getId(), DEFAULT_SMS_PACKAGE_NAME); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, sbn, channel, mSmsHelper); assertTrue(entry.involvesPeople()); } @Test public void testHasPerson_doesntMatchDefaultSmsApp() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); StatusBarNotification sbn = generateSbn(channel.getId(), "abc"); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, sbn, channel, mSmsHelper); assertFalse(entry.involvesPeople()); } @Test public void testIsInboxStyle() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); Notification n = new Notification.Builder(mContext, channel.getId()) .setStyle(new Notification.InboxStyle()) .build(); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertTrue(entry.hasStyle(Notification.InboxStyle.class)); } @Test public void testIsMessagingStyle() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); Notification n = new Notification.Builder(mContext, channel.getId()) .setStyle(new Notification.MessagingStyle("")) .build(); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertTrue(entry.hasStyle(Notification.MessagingStyle.class)); } @Test public void testIsNotPersonStyle() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); Notification n = new Notification.Builder(mContext, channel.getId()) .setStyle(new Notification.BigPictureStyle()) .build(); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertFalse(entry.hasStyle(Notification.InboxStyle.class)); assertFalse(entry.hasStyle(Notification.MessagingStyle.class)); } @Test public void testIsAudioAttributes() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); channel.setSound(null, new AudioAttributes.Builder().setUsage(USAGE_ALARM).build()); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper); assertTrue(entry.isAudioAttributesUsage(USAGE_ALARM)); } @Test public void testIsNotAudioAttributes() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(channel.getId()), channel, mSmsHelper); assertFalse(entry.isAudioAttributesUsage(USAGE_ALARM)); } @Test public void testIsCategory() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); Notification n = new Notification.Builder(mContext, channel.getId()) .setCategory(Notification.CATEGORY_EMAIL) .build(); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertTrue(entry.isCategory(Notification.CATEGORY_EMAIL)); assertFalse(entry.isCategory(Notification.CATEGORY_MESSAGE)); } @Test public void testIsOngoing() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); Notification n = new Notification.Builder(mContext, channel.getId()) .setFlag(FLAG_FOREGROUND_SERVICE, true) .build(); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertTrue(entry.isOngoing()); } @Test public void testIsNotOngoing() { NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); Notification n = new Notification.Builder(mContext, channel.getId()) .setFlag(0x00000800 /* FLAG_CAN_COLORIZE */, true) .build(); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertFalse(entry.isOngoing()); } @Test public void testShrinkNotification() { Notification n = new Notification.Builder(mContext, "") .setLargeIcon(Icon.createWithResource( mContext, android.R.drawable.alert_dark_frame)) .setSmallIcon(android.R.drawable.sym_def_app_icon) .build(); n.largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565); NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); NotificationEntry entry = new NotificationEntry( mContext, mPackageManager, generateSbn(n), channel, mSmsHelper); assertNull(entry.getNotification().getSmallIcon()); assertNull(entry.getNotification().getLargeIcon()); assertNull(entry.getNotification().largeIcon); assertNull(entry.getNotification().extras.getParcelable(Notification.EXTRA_LARGE_ICON)); } }