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