NotificationInflaterTest.java revision 70950def80d1aa5938c104e125635e0d42933ba7
1/* 2 * Copyright (C) 2017 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 17package com.android.systemui.statusbar.notification; 18 19import static com.android.systemui.statusbar.notification.NotificationInflater.FLAG_REINFLATE_ALL; 20 21import static org.mockito.Mockito.spy; 22import static org.mockito.Mockito.times; 23import static org.mockito.Mockito.verify; 24 25import android.app.Notification; 26import android.content.Context; 27import android.service.notification.StatusBarNotification; 28import android.support.test.InstrumentationRegistry; 29import android.support.test.annotation.UiThreadTest; 30import android.support.test.filters.FlakyTest; 31import android.support.test.filters.SmallTest; 32import android.support.test.runner.AndroidJUnit4; 33import android.widget.RemoteViews; 34 35import com.android.systemui.R; 36import com.android.systemui.statusbar.ExpandableNotificationRow; 37import com.android.systemui.statusbar.NotificationData; 38import com.android.systemui.statusbar.NotificationTestHelper; 39 40import org.junit.Assert; 41import org.junit.Before; 42import org.junit.Ignore; 43import org.junit.Test; 44import org.junit.runner.RunWith; 45 46import java.util.concurrent.CountDownLatch; 47 48@SmallTest 49@RunWith(AndroidJUnit4.class) 50@FlakyTest 51public class NotificationInflaterTest { 52 53 private Context mContext; 54 private NotificationInflater mNotificationInflater; 55 private Notification.Builder mBuilder; 56 private ExpandableNotificationRow mRow; 57 58 @Before 59 public void setUp() throws Exception { 60 mContext = InstrumentationRegistry.getTargetContext(); 61 mBuilder = new Notification.Builder(mContext).setSmallIcon( 62 R.drawable.ic_person) 63 .setContentTitle("Title") 64 .setContentText("Text") 65 .setStyle(new Notification.BigTextStyle().bigText("big text")); 66 ExpandableNotificationRow row = new NotificationTestHelper(mContext).createRow( 67 mBuilder.build()); 68 mRow = spy(row); 69 mNotificationInflater = new NotificationInflater(mRow); 70 mNotificationInflater.setInflationCallback(new NotificationInflater.InflationCallback() { 71 @Override 72 public void handleInflationException(StatusBarNotification notification, 73 Exception e) { 74 } 75 76 @Override 77 public void onAsyncInflationFinished(NotificationData.Entry entry) { 78 } 79 }); 80 } 81 82 @Test 83 @UiThreadTest 84 public void testIncreasedHeadsUpBeingUsed() { 85 mNotificationInflater.setUsesIncreasedHeadsUpHeight(true); 86 Notification.Builder builder = spy(mBuilder); 87 mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext); 88 verify(builder).createHeadsUpContentView(true); 89 } 90 91 @Test 92 @UiThreadTest 93 public void testIncreasedHeightBeingUsed() { 94 mNotificationInflater.setUsesIncreasedHeight(true); 95 Notification.Builder builder = spy(mBuilder); 96 mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext); 97 verify(builder).createContentView(true); 98 } 99 100 @Test 101 public void testInflationCallsUpdated() throws Exception { 102 runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(), 103 mNotificationInflater); 104 verify(mRow).onNotificationUpdated(); 105 } 106 107 @Test 108 public void testInflationCallsOnlyRightMethod() throws Exception { 109 mRow.getPrivateLayout().removeAllViews(); 110 mRow.getEntry().cachedBigContentView = null; 111 runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews( 112 NotificationInflater.FLAG_REINFLATE_EXPANDED_VIEW), mNotificationInflater); 113 Assert.assertTrue(mRow.getPrivateLayout().getChildCount() == 1); 114 Assert.assertTrue(mRow.getPrivateLayout().getChildAt(0) 115 == mRow.getPrivateLayout().getExpandedChild()); 116 verify(mRow).onNotificationUpdated(); 117 } 118 119 @Test 120 public void testInflationThrowsErrorDoesntCallUpdated() throws Exception { 121 mRow.getPrivateLayout().removeAllViews(); 122 mRow.getStatusBarNotification().getNotification().contentView 123 = new RemoteViews(mContext.getPackageName(), R.layout.status_bar); 124 runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(), 125 true /* expectingException */, mNotificationInflater); 126 Assert.assertTrue(mRow.getPrivateLayout().getChildCount() == 0); 127 verify(mRow, times(0)).onNotificationUpdated(); 128 } 129 130 @Test 131 public void testAsyncTaskRemoved() throws Exception { 132 mRow.getEntry().abortTask(); 133 runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(), 134 mNotificationInflater); 135 Assert.assertNull(mRow.getEntry().getRunningTask() ); 136 } 137 138 public static void runThenWaitForInflation(Runnable block, 139 NotificationInflater inflater) throws Exception { 140 runThenWaitForInflation(block, false /* expectingException */, inflater); 141 } 142 143 private static void runThenWaitForInflation(Runnable block, boolean expectingException, 144 NotificationInflater inflater) throws Exception { 145 com.android.systemui.util.Assert.isNotMainThread(); 146 CountDownLatch countDownLatch = new CountDownLatch(1); 147 final ExceptionHolder exceptionHolder = new ExceptionHolder(); 148 inflater.setInflationCallback(new NotificationInflater.InflationCallback() { 149 @Override 150 public void handleInflationException(StatusBarNotification notification, 151 Exception e) { 152 if (!expectingException) { 153 exceptionHolder.setException(e); 154 } 155 countDownLatch.countDown(); 156 } 157 158 @Override 159 public void onAsyncInflationFinished(NotificationData.Entry entry) { 160 if (expectingException) { 161 exceptionHolder.setException(new RuntimeException( 162 "Inflation finished even though there should be an error")); 163 } 164 countDownLatch.countDown(); 165 } 166 }); 167 block.run(); 168 countDownLatch.await(); 169 if (exceptionHolder.mException != null) { 170 throw exceptionHolder.mException; 171 } 172 } 173 174 private static class ExceptionHolder { 175 private Exception mException; 176 177 public void setException(Exception exception) { 178 mException = exception; 179 } 180 } 181} 182