Home | History | Annotate | Download | only in app
      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