Home | History | Annotate | Download | only in automatic
      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 
     17 package com.android.storagemanager.automatic;
     18 
     19 import android.app.Notification;
     20 import android.app.NotificationManager;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.provider.Settings;
     24 import com.android.storagemanager.testing.TestingConstants;
     25 import org.junit.Before;
     26 import org.junit.Test;
     27 import org.junit.runner.RunWith;
     28 import org.mockito.ArgumentCaptor;
     29 import org.mockito.Mock;
     30 import org.mockito.MockitoAnnotations;
     31 import org.robolectric.RobolectricTestRunner;
     32 import org.robolectric.annotation.Config;
     33 import org.robolectric.shadows.ShadowApplication;
     34 
     35 import java.util.concurrent.TimeUnit;
     36 
     37 import static com.google.common.truth.Truth.assertThat;
     38 import static org.mockito.Matchers.any;
     39 import static org.mockito.Matchers.anyInt;
     40 import static org.mockito.Mockito.*;
     41 
     42 @RunWith(RobolectricTestRunner.class)
     43 @Config(manifest=TestingConstants.MANIFEST, sdk=TestingConstants.SDK_VERSION)
     44 public 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