1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.storagemanager.automatic; 18 19import android.app.Notification; 20import android.app.NotificationManager; 21import android.content.Context; 22import android.content.Intent; 23import android.provider.Settings; 24import com.android.storagemanager.testing.TestingConstants; 25import org.junit.Before; 26import org.junit.Test; 27import org.junit.runner.RunWith; 28import org.mockito.ArgumentCaptor; 29import org.mockito.Mock; 30import org.mockito.MockitoAnnotations; 31import org.robolectric.RobolectricTestRunner; 32import org.robolectric.annotation.Config; 33import org.robolectric.shadows.ShadowApplication; 34 35import java.util.concurrent.TimeUnit; 36 37import static com.google.common.truth.Truth.assertThat; 38import static org.mockito.Matchers.any; 39import static org.mockito.Matchers.anyInt; 40import static org.mockito.Mockito.*; 41 42@RunWith(RobolectricTestRunner.class) 43@Config(manifest=TestingConstants.MANIFEST, sdk=TestingConstants.SDK_VERSION) 44public class NotificationControllerTest { 45 @Mock 46 private NotificationManager mNotificationManager; 47 private Context mContext; 48 private NotificationController mController; 49 private FakeClock mClock; 50 51 @Before 52 public void setUp() { 53 MockitoAnnotations.initMocks(this); 54 ShadowApplication application = ShadowApplication.getInstance(); 55 application.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager); 56 mController = new NotificationController(); 57 mClock = new FakeClock(); 58 mController.setClock(mClock); 59 mContext = application.getApplicationContext(); 60 } 61 62 @Test 63 public void testShouldShowNotificationFirstTime() { 64 mController.onReceive(mContext, 65 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 66 67 verify(mNotificationManager).notify(anyInt(), any(Notification.class)); 68 mController.onReceive(mContext, 69 getNotificationIntent(NotificationController.INTENT_ACTION_DISMISS, 1)); 70 verify(mNotificationManager).cancel(1); 71 } 72 73 @Test 74 public void testNotificationNotShownIfShownTooManyTimes() { 75 // Show the notification 4 times. 76 for (int i = 1; i < 5; i++) { 77 mController.onReceive(mContext, 78 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 79 verify(mNotificationManager, times(i)).notify(anyInt(), any(Notification.class)); 80 mController.onReceive(mContext, 81 getNotificationIntent(NotificationController.INTENT_ACTION_NO_THANKS, 1)); 82 verify(mNotificationManager, times(i)).cancel(1); 83 mClock.time += TimeUnit.DAYS.toMillis(91); 84 } 85 86 // The next time should show nothing. 87 mController.onReceive(mContext, 88 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 89 verifyZeroInteractions(mNotificationManager); 90 } 91 92 @Test 93 public void testNotificationNotShownIfDismissedTooManyTimes() { 94 // Show the notification 9 times. 95 for (int i = 0; i < 9; i++) { 96 mController.onReceive(mContext, 97 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 98 verify(mNotificationManager, times(i + 1)).notify(anyInt(), any(Notification.class)); 99 mController.onReceive(mContext, 100 getNotificationIntent(NotificationController.INTENT_ACTION_DISMISS, 1)); 101 verify(mNotificationManager, times(i + 1)).cancel(1); 102 mClock.time += TimeUnit.DAYS.toMillis(14); 103 } 104 105 // The next time should show nothing. 106 mController.onReceive(mContext, 107 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 108 verifyZeroInteractions(mNotificationManager); 109 } 110 111 @Test 112 public void testDismissNotificationDelay() { 113 mController.onReceive(mContext, 114 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 115 verify(mNotificationManager).notify(anyInt(), any(Notification.class)); 116 mController.onReceive(mContext, 117 getNotificationIntent(NotificationController.INTENT_ACTION_DISMISS, 1)); 118 verify(mNotificationManager).cancel(1); 119 120 // Another attempt should not show a notification. 121 mController.onReceive(mContext, 122 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 123 verifyZeroInteractions(mNotificationManager); 124 125 // The notification should show against after 14 days. 126 mClock.time = TimeUnit.DAYS.toMillis(14); 127 mController.onReceive(mContext, 128 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 129 verify(mNotificationManager, times(2)).notify(anyInt(), any(Notification.class)); 130 } 131 132 @Test 133 public void testNoThanksNotificationDelay() { 134 mController.onReceive(mContext, 135 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 136 verify(mNotificationManager).notify(anyInt(), any(Notification.class)); 137 mController.onReceive(mContext, 138 getNotificationIntent(NotificationController.INTENT_ACTION_NO_THANKS, 1)); 139 verify(mNotificationManager).cancel(1); 140 141 // Another attempt should not show a notification. 142 mController.onReceive(mContext, 143 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 144 verifyZeroInteractions(mNotificationManager); 145 146 // The notification should show against after 90 days. 147 mClock.time = TimeUnit.DAYS.toMillis(90); 148 mController.onReceive(mContext, 149 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 150 verify(mNotificationManager, times(2)).notify(anyInt(), any(Notification.class)); 151 } 152 153 @Test 154 public void testActivateStorageManagerIntent() throws Exception { 155 mController.onReceive(mContext, 156 new Intent(NotificationController.INTENT_ACTION_ACTIVATE_ASM)); 157 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 158 Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED)).isEqualTo(1); 159 } 160 161 @Test 162 public void testNotificationIsLocalOnly(){ 163 ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class); 164 mController.onReceive(mContext, 165 new Intent(NotificationController.INTENT_ACTION_SHOW_NOTIFICATION)); 166 verify(mNotificationManager).notify(anyInt(), captor.capture()); 167 assertThat(captor.getValue().flags & Notification.FLAG_LOCAL_ONLY) 168 .isEqualTo(Notification.FLAG_LOCAL_ONLY); 169 } 170 171 @Test 172 public void testIntentFromNotificationAreExplicit() { 173 Intent baseIntent = 174 mController.getBaseIntent(mContext, NotificationController.INTENT_ACTION_DISMISS); 175 176 assertThat(baseIntent.getComponent().getPackageName()) 177 .isEqualTo("com.android.storagemanager"); 178 assertThat(baseIntent.getComponent().getClassName()) 179 .isEqualTo("com.android.storagemanager.automatic.NotificationController"); 180 } 181 182 @Test 183 public void testTappingGoesToStorageSettings() { 184 mController.onReceive(mContext, new Intent(NotificationController.INTENT_ACTION_TAP)); 185 186 assertThat(ShadowApplication.getInstance().getNextStartedActivity().getAction()) 187 .isEqualTo(Settings.ACTION_INTERNAL_STORAGE_SETTINGS); 188 } 189 190 private Intent getNotificationIntent(String action, int id) { 191 Intent intent = new Intent(action); 192 intent.putExtra(NotificationController.INTENT_EXTRA_ID, id); 193 return intent; 194 } 195 196 private class FakeClock extends NotificationController.Clock { 197 public long time = 0L; 198 199 @Override 200 public long currentTimeMillis() { 201 return time; 202 } 203 } 204} 205