1 /* 2 * Copyright (C) 2011 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 android.app; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.net.Uri; 22 import android.os.Build; 23 import android.os.RemoteException; 24 import android.os.SystemClock; 25 import android.support.test.uiautomator.UiDevice; 26 import android.test.InstrumentationTestCase; 27 import android.test.RepetitiveTest; 28 import android.util.Log; 29 30 import java.lang.InterruptedException; 31 import java.lang.reflect.Method; 32 import java.util.Random; 33 34 /** 35 * Test which spams notification manager with a large number of notifications, for both stress and 36 * performance testing. 37 */ 38 public class NotificationStressTest extends InstrumentationTestCase { 39 40 private static final int NUM_ITERATIONS = 200; 41 private static final int NUM_ITERATIONS_2 = 30; 42 private static final int LONG_TIMEOUT = 2000; 43 // 49 notifications per app: defined as Variable MAX_PACKAGE_NOTIFICATIONS in 44 // NotificationManagerService.java 45 private static final int MAX_NOTIFCATIONS = 49; 46 private static final int[] ICONS = new int[] { 47 android.R.drawable.stat_notify_call_mute, 48 android.R.drawable.stat_notify_chat, 49 android.R.drawable.stat_notify_error, 50 android.R.drawable.stat_notify_missed_call, 51 android.R.drawable.stat_notify_more, 52 android.R.drawable.stat_notify_sdcard, 53 android.R.drawable.stat_notify_sdcard_prepare, 54 android.R.drawable.stat_notify_sdcard_usb, 55 android.R.drawable.stat_notify_sync, 56 android.R.drawable.stat_notify_sync_noanim, 57 android.R.drawable.stat_notify_voicemail, 58 }; 59 60 private final Random mRandom = new Random(); 61 private Context mContext; 62 private NotificationManager mNotificationManager; 63 private UiDevice mDevice = null; 64 private int mNotifyId = 0; 65 66 @Override 67 protected void setUp() throws Exception { 68 super.setUp(); 69 mDevice = UiDevice.getInstance(getInstrumentation()); 70 mContext = getInstrumentation().getContext(); 71 mNotificationManager = (NotificationManager) mContext.getSystemService( 72 Context.NOTIFICATION_SERVICE); 73 mDevice.setOrientationNatural(); 74 mNotificationManager.cancelAll(); 75 } 76 77 @Override 78 protected void tearDown() throws Exception { 79 mDevice.unfreezeRotation(); 80 mNotificationManager.cancelAll(); 81 mDevice.waitForIdle(); 82 super.tearDown(); 83 } 84 85 @RepetitiveTest(numIterations = NUM_ITERATIONS) 86 public void testNotificationStress() { 87 // Cancel one of every five notifications to vary load on notification manager 88 if (mNotifyId % 5 == 4) { 89 mNotificationManager.cancel(mNotifyId - 4); 90 } 91 sendNotification(mNotifyId++, "testNotificationStressNotify"); 92 } 93 94 @RepetitiveTest(numIterations = NUM_ITERATIONS_2) 95 public void testNotificationsWithShadeStress() throws Exception { 96 mDevice.openNotification(); 97 Thread.sleep(LONG_TIMEOUT); 98 for (int j = 0; j < MAX_NOTIFCATIONS; j++) { 99 sendNotification(mNotifyId++, "testNotificationStressNotify"); 100 } 101 Thread.sleep(LONG_TIMEOUT); 102 assertTrue(mNotificationManager.getActiveNotifications().length == MAX_NOTIFCATIONS); 103 for (int j = 0; j < MAX_NOTIFCATIONS; j++) { 104 mNotificationManager.cancel(--mNotifyId); 105 } 106 if (isLockScreen()) { 107 fail("Notification stress test failed, back to lockscreen"); 108 } 109 } 110 111 private void sendNotification(int id, CharSequence text) { 112 // Fill in arbitrary content 113 Intent intent = new Intent(Intent.ACTION_VIEW); 114 PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0); 115 CharSequence title = text + " " + id; 116 CharSequence subtitle = String.valueOf(System.currentTimeMillis()); 117 // Create "typical" notification with random icon 118 Notification notification = new Notification.Builder(mContext) 119 .setSmallIcon(ICONS[mRandom.nextInt(ICONS.length)]) 120 .setTicker(text) 121 .setWhen(System.currentTimeMillis()) 122 .setContentTitle(title) 123 .setContentText(subtitle) 124 .setContentIntent(pendingIntent) 125 .setPriority(Notification.PRIORITY_HIGH) 126 .build(); 127 mNotificationManager.notify(id, notification); 128 //update rate limit is 50 notifications/second. 129 SystemClock.sleep(20); 130 } 131 132 private boolean isLockScreen() { 133 KeyguardManager myKM = (KeyguardManager) mContext 134 .getSystemService(Context.KEYGUARD_SERVICE); 135 if (myKM.inKeyguardRestrictedInputMode()) { 136 return true; 137 } else { 138 return false; 139 } 140 } 141 } 142